1. 程式人生 > >支付相關(一):APP支付寶支付(JAVA服務端開發)

支付相關(一):APP支付寶支付(JAVA服務端開發)

開發環境:springboot

最近一年兩個專案開發,其中APP支付這塊用到了微信支付,支付寶支付,以及轉賬到微信零錢,轉賬到支付寶賬號等功能,下面會分成4個文章來介紹。

具體的開通微信和支付寶問題我不再敘述,直接上程式碼,程式碼會打包放在CSDN去下載,沒有分的可以找我。

簽約注意下支付寶和微信都要開通APP支付,支付寶開通單筆轉賬的支付寶賬號,微信開通轉賬到零錢等

先從支付寶開始:

首先在pom.xml檔案中新增支付寶SDK依賴

1支付寶引數配置類

/**
 * 支付寶配置
 */
public class AliPayConfig {
        //appid
        public static String APP_ID_USER = "";
        //應用私鑰
        public static String PRIVATE_KEY = "";
        //應用公鑰
        public static String APP_PUBLIC_KEY = "";
        //支付寶公鑰
        public static String ALI_PUBLIC_KEY ="";
        //字符集
        public static String CHARSET = "utf-8";
        //URLs支付
        public static String URL = "https://openapi.alipay.com/gateway.do";
        //資料格式
        public static String FORMAT = "json";
        //加密方式
        public static String SIGN_TYPE = "RSA2";
        //接收支付寶回撥地址notify_url //測試時候可以對映到本地地址可測試,不一定非要部署到線上
        public static String NOTIFY_URL="可訪問的線上地址;
       

         //以下為支付寶授權登入所用
        //授權服務對應的名稱
        public static String AUTH_API_NAME="com.alipay.account.auth";
        //授權服務介面名稱方法
        public static String AUTH_API_METHOD="alipay.open.auth.sdk.code.get";
        //授權app_name呼叫來源方的標識
        public static String AUTH_APP_NAME="mc";
        //呼叫業務的型別,常量值為
        public static String AUTH_BIZ_TYPE="openservice";
        // pid簽約的支付寶賬號對應的支付寶唯一使用者號
        public static String AUTH_PID="";
        //	產品碼
        public static String AUTH_PRODUCT_ID="APP_FAST_LOGIN";
        //授權範圍
        public static String AUTH_SCOPE="kuaijie";
        //	標識授權型別,
        public static String AUTH_TYPE="AUTHACCOUNT";
        //

}

上面引數配置一定要區分好,尤其是應用公鑰和支付寶公鑰。

2支付寶工具類,DTO,等

import java.io.Serializable;


/**
* @Description:    訂單表用dto
*/
public class OrderDto implements Serializable {
    private static final long serialVersionUID = -27273789824211424L;
    private Integer userId;   //使用者ID
    private String orderNo; // 商戶訂單號,適配每個渠道對此引數的要求,必須在商戶系統內唯一
    private Float amount; // 訂單總金額(必須大於0),單位為對應幣種的最小貨幣單位,人民幣為分
    private String subject; // 商品標題,該引數最長為 32 個 Unicode 字元
    private String body; // 商品描述資訊,該引數最長為 128 個 Unicode 字元
    private String description; // 訂單附加說明,最多 255 個 Unicode 字元
    private String wxZfbNum;//微信或支付寶支付成功微信支付寶生成的訂單號
    private String aliAuthCode;//支付寶auth_code
   
    public Float getAmount() {
        return amount;
    }

    public void setAmount(Float amount) {
        this.amount = amount;
    }

    public String getSubject() {
        return subject;
    }

    public void setSubject(String subject) {
        this.subject = subject;
    }

    public String getBody() {
        return body;
    }

    public void setBody(String body) {
        this.body = body;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }


    
    public Integer getUserId() {
        return userId;
    }

    public void setUserId(Integer userId) {
        this.userId = userId;
    }

    public String getOrderNo() {
        return orderNo;
    }

    public void setOrderNo(String orderNo) {
        this.orderNo = orderNo;
    }

   

    public String getWxZfbNum() {
        return wxZfbNum;
    }

    public void setWxZfbNum(String wxZfbNum) {
        this.wxZfbNum = wxZfbNum;
    }

    public String getAliAuthCode() {
        return aliAuthCode;
    }

    public void setAliAuthCode(String aliAuthCode) {
        this.aliAuthCode = aliAuthCode;
    }

 
}
import java.io.Serializable;
import java.util.List;

public class ResultModel implements Serializable {

    private static final long serialVersionUID = -2376100248939876442L;

    private Integer status;//狀態

    private String message;//返回資訊,成功或者失敗資訊

    private String  pkColumn;//生成主鍵的名稱

    private Integer pk;//插入操作時返回的主鍵

    private Integer maxId;//最大查詢返回id

    private List<Object> resultList;//查詢操作時返回的結果列表

    private Object resultObject;


    public Integer getStatus() {
        return status;
    }

    public void setStatus(Integer status) {
        this.status = status;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public Integer getPk() {
        return pk;
    }

    public String getPkColumn() {
        return pkColumn;
    }

    public void setPkColumn(String pkColumn) {
        this.pkColumn = pkColumn;
    }

    public void setPk(Integer pk) {
        this.pk = pk;
    }

    public Integer getMaxId() {
        return maxId;
    }

    public void setMaxId(Integer maxId) {
        this.maxId = maxId;
    }

    public List<Object> getResultList() {
        return resultList;
    }

    public void setResultList(List<Object> resultList) {
        this.resultList = resultList;
    }

    public Object getResultObject() {
        return resultObject;
    }

    public void setResultObject(Object resultObject) {
        this.resultObject = resultObject;
    }
}
import java.util.Date;

/**
 * 生成訂單編號使用
 */
public class UUID {
    private static Date date = new Date();
    private static StringBuilder buf = new StringBuilder();
    private static int seq = 0;
    private static final int ROTATION = 99999;

    public static synchronized long next() {
        if (seq > ROTATION)
            seq = 0;
        buf.delete(0, buf.length());
        date.setTime(System.currentTimeMillis());
        String str = String.format("%1$tY%1$tm%1$td%1$tk%1$tM%1$tS%2$05d", date, seq++);
        return Long.parseLong(str);
    }

    private UUID(){

    }
}



3支付程式碼實現

app請求後臺 和 支付寶支付成功通知

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.*;
import com.alipay.api.response.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;


import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;

/**

 * 支付寶訂單支付 
 */
@RestController
@RequestMapping("/pay/alipay")
public class AliPayController {

    //@Autowired
   // private IMicroAliPayService microAliPayService;
    @PostMapping("aliPayOrder")
    public ResultModel aliPayOrder(@RequestBody OrderDto dto, HttpServletRequest request,
                                   HttpServletResponse response) {
        ResultModel resultModel = new ResultModel();
        //例項化客戶端
        AlipayClient alipayClient = new DefaultAlipayClient(AliPayConfig.URL, AliPayConfig.APP_ID_USER, AliPayConfig.PRIVATE_KEY, AliPayConfig.FORMAT,AliPayConfig.CHARSET ,AliPayConfig.ALI_PUBLIC_KEY, AliPayConfig.SIGN_TYPE);
        //例項化具體API對應的request類,類名稱和介面名稱對應,當前呼叫介面名稱:alipay.trade.app.pay
        AlipayTradeAppPayRequest aliRequest = new AlipayTradeAppPayRequest();
        //SDK已經封裝掉了公共引數,這裡只需要傳入業務引數。以下方法為sdk的model入參方式(model和biz_content同時存在的情況下取biz_content)。
        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
        String out_trade_no = String.valueOf(UUID.next());
        model.setBody(dto.getBody());
        model.setSubject(dto.getSubject());
        model.setOutTradeNo(out_trade_no);
        model.setTimeoutExpress("30m");
        model.setTotalAmount(dto.getAmount()+"");//訂單價格
        model.setProductCode("QUICK_MSECURITY_PAY");
        aliRequest.setBizModel(model);
      
        aliRequest.setNotifyUrl(AliPayConfig.NOTIFY_URL);//3為充值訂單
       
        String orderStr = "";
        try {
            //這裡和普通的介面呼叫不同,使用的是sdkExecute
            AlipayTradeAppPayResponse aliResponse = alipayClient.sdkExecute(aliRequest);
            orderStr = aliResponse.getBody();//
            //我是在這把支付訂單資訊做的儲存,生成預支付訂單,把orderStr傳給APP進行處理並支付
            resultModel.setStatus(1);
            resultModel.setMessage("生成預支付訂單成功");
            resultModel.setResultObject(orderStr);
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        
        return resultModel;
    }


}
/**
     * 支付成功接收支付寶支付成功通知
     *
     * @param request
     * @throws UnsupportedEncodingException,AlipayApiException
     */
    @PostMapping("aliPayInquiryNotify")
    public void aliPayNotify(HttpServletRequest request) throws UnsupportedEncodingException, AlipayApiException {
        //獲取支付寶POST過來反饋資訊
        Map<String, String> params = new HashMap<String, String>();
        Map requestParams = request.getParameterMap();
        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            if (name.equals("trade_status")) {

                System.out.println("交易狀態為:" + valueStr);
               
            }
            //亂碼解決,這段程式碼在出現亂碼時使用。
            //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put(name, valueStr);
        }
       
        //切記alipaypublickey是支付寶的公鑰,別錯放應用公鑰,如果再驗籤這出問題,先排查是否放錯公鑰,一般是這個問題造成
        //boolean AlipaySignature.rsaCheckV1(Map<String, String> params, String publicKey, String charset, String sign_type)
        boolean flag = AlipaySignature.rsaCheckV1(params, AliPayConfig.ALI_PUBLIC_KEY, AliPayConfig.CHARSET, AliPayConfig.SIGN_TYPE);
        //獲取支付寶的通知返回引數
       

        if (flag) {//驗證成功
            String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");
            //支付寶交易號
            String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), "UTF-8");
            //客戶訂單編號
            String auth_app_id = new String(request.getParameter("auth_app_id").getBytes("ISO-8859-1"), "UTF-8");
            //買家登入支付寶id
            String buyer_logon_id = new String(request.getParameter("buyer_logon_id").getBytes("ISO-8859-1"), "UTF-8");
            //交易時間
            String gmt_payment = new String(request.getParameter("gmt_payment").getBytes("ISO-8859-1"), "UTF-8");
            //交易金額
            String invoice_amount = new String(request.getParameter("invoice_amount").getBytes("ISO-8859-1"), "UTF-8");

            //這裡進行你的訂單狀態的更改,以及你的業務處理。處理完畢打印出success後,支付寶只會下發一次,否則會下發多次,可以檢視文件理解下
             
             System.out.println("success");
    
    
        } else {//驗證失敗
            //TODO service 生成訂單支付失敗歷史記錄
            
            System.out.println("fail");
        }
        
    }

4以上三步就是支付寶支付JAVA服務端的開發