手機APP如何接入支付寶支付

盧水發發表於2020-03-04

1、進入支付寶螞蟻金服開放平臺建立一個應用

螞蟻金服支付寶開發者中心 網址如下:developers.alipay.com/development…

手機APP如何接入支付寶支付

可以看到有一個(網頁&移動應用的),進入開放平臺建立一個這樣的應用就可以了

首次登入會讓你填寫加入開放平臺的資訊,按照提示操作完就行:

手機APP如何接入支付寶支付

建立完應用後你將得到以下頁面:

手機APP如何接入支付寶支付

也可以給你建立的應用增加能力,比如APP支付能力,獲取會員資訊等等。

手機APP如何接入支付寶支付

2、接入支付sdk,服務端jar包

<dependency>
  <groupId>com.alipay.sdk</groupId>
  <artifactId>alipay-sdk-java</artifactId>
  <version>4.3.0.ALL</version>
</dependency>
複製程式碼

3、下單處理程式碼

AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
model.setBody("購買["+placeOrderForm.getProductName()+"]");
model.setSubject("購買xxx["+placeOrderForm.getProductName()+"]");
model.setOutTradeNo(order.getUuid());
model.setTotalAmount(String.valueOf(order.getTotalOrderPrice()));
try {
	String orderString = alipaySao.createALipayTrade(model);
	Map<String,Object> resultMap = ImmutableMap.of("orderString",orderString,"orderNo",order.getUuid());
	//更新訂單為支付中
	this.updatePayStatus(order.getUuid(),PayStatusEnum.PAYING.getCode(),"");
	return ResponseVo.buildSuccessResponse(resultMap);
} catch (AlipayApiException e) {
	log.error("AlipayApiException e={}",e);
	return ResponseVo.buildResponse(ResponseEnum.ALIPAY_ERROR);
}
複製程式碼

4、與支付寶進行通訊

初始化:
// 例項化客戶端
alipayClient = new DefaultAlipayClient(
        AlipayConfig.ALIPAY_URL,
        AlipayConfig.APP_ID,
        AlipayConfig.PRIVATE_KEY,
        AlipayConfig.FORMAT,
        AlipayConfig.CHARSET,
        AlipayConfig.ALIPAY_PUBLIC_KEY,
        AlipayConfig.SIGN_TYPE);

/**
 * 支付客戶端
 * @throws AlipayApiException
 * @return
 */
@Override
public String createALipayTrade(AlipayTradeAppPayModel model) throws AlipayApiException {
    // 例項化具體API對應的request類,類名稱和介面名稱對應,當前呼叫介面名稱:alipay.trade.app.pay
    AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
    // SDK已經封裝掉了公共引數,這裡只需要傳入業務引數。以下方法為sdk的model入參方式(model和biz_content同時存在的情況下取biz_content)。
    model.setTimeoutExpress("60m");
    model.setProductCode("QUICK_MSECURITY_PAY");
    request.setBizModel(model);
    request.setNotifyUrl(AlipayConfig.CALLBACK_URL);
    //非同步回撥url
    // 這裡和普通的介面呼叫不同,使用的是sdkExecute
    AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
    log.info("apliay.response.body={}",response.getBody());
    //就是orderString 可以直接給客戶端請求,無需再做處理。
    return response.getBody();
}
複製程式碼

5、支付寶相關配置(實際應用建議使用配置項管理)

package com.fast.tpp.dto;

public class AlipayConfig {

        /**
         * 簽約的支付寶賬號對應的支付寶唯一使用者號,以2088開頭的16位純數字組成
         */
        public static final String PID = "xx";

        /**
         * 正式環境請求地址
         */
        public static String ALIPAY_URL = "https://openapi.alipay.com/gateway.do";

        /**
         * 支付寶分配給開發者的應用ID
         *
         */
        public static String APP_ID = "xxx";

        /**
         * 僅支援JSON
         */
        public static String FORMAT = "JSON";

        /**
         * 請求使用的編碼格式
         */
        public static String CHARSET = "utf-8";

        /**
         * 商戶生成簽名字串所使用的簽名演算法型別
         */
        public static String SIGN_TYPE = "RSA2";

        /**
         * 支付寶公鑰
         */
        public static String ALIPAY_PUBLIC_KEY =xxx;
        /**
         * 商戶私鑰
         */
        public static String PRIVATE_KEY =XXX";

        /**
         * 回撥地址
         */
        public static String CALLBACK_URL = "xxx";
}

複製程式碼

6、支付狀態設定

package com.fast.common.enums;

/**
 * 支付狀態
 */
public enum PayStatusEnum {


	NOT_PAY(0,"未支付"),

	PAYING(1, "支付中"),

	SUCCESS(2,"支付成功"),

	FAILUE(3, "支付失敗"),

    ;

	private int code;
	private String value;

	PayStatusEnum(int code, String value){
		this.code = code;
		this.value = value;
	}
	
	// 獲取對應的文字
	public static String getName(int code) {
		for (PayStatusEnum c : PayStatusEnum.values()) {
		  if (c.getCode() == code) {
		     return c.value;
		  }
		}
		return null;
	}
	
	public int getCode() {
		return code;
	}

	public void setCode(int code) {
		this.code = code;
	}

	public String getValue() {
		return value;
	}

	public void setValue(String value) {
		this.value = value;
	}
}

複製程式碼

7、回撥通知介面

/**
	 * 支付寶支付通知
	 * @param request
	 * @param response
	 * @return
	 * @throws IOException
	 */
	@RequestMapping(value="/alipayNotice.do",method = RequestMethod.POST)
	@ResponseBody
	@NoneAuth
	@SysLog(actionName = "支付寶支付通知")
	public String alipayNotice(HttpServletRequest request, HttpServletResponse response) throws IOException {
		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] + ",";
			}

			params.put(name, valueStr);
		}
		// 切記alipaypublickey是支付寶的公鑰,請去open.alipay.com對應應用下檢視。
		try {
			boolean flag = AlipaySignature.rsaCheckV1(params, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.CHARSET,
					AlipayConfig.SIGN_TYPE);
			if (flag) {
				String tradeStatus = params.get("trade_status");
				String outTradeNo = params.get("out_trade_no");
				String tradeNo = params.get("trade_no");
				//購買者使用者ID
				String openId = params.get("buyer_logon_id");
				this.orderService.alipayNotice(tradeStatus,outTradeNo,tradeNo,openId);
				if ("TRADE_SUCCESS".equals(tradeStatus)){
					return "success";
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "fail";
	}
	
	
	對應的service方法為:
	/**
	 * 支付寶支付通知
	 * @param tradeStatus
	 * @param outTradeNo
	 * @param tradeNo
	 * @param openId
	 */
	public void alipayNotice(String tradeStatus, String outTradeNo, String tradeNo, String openId){
		log.info("alipayNotice outTradeNo={} tradeStatus={}",outTradeNo,tradeNo);
		String orderNo = outTradeNo;
		if ("TRADE_SUCCESS".equals(tradeStatus)) {
			// 交易支付成功的執行相關業務邏輯
			Order order = this.getOrderByOrderNo(orderNo);
			if(null==order){
				return;
			}
			//只有在未支付成功的狀態下才可以發簡訊和更新生效時間
			if (order.getPayStatus()!=PayStatusEnum.SUCCESS.getCode()){
				this.orderMapper.updatePrepayId(tradeNo,orderNo);
				//處理支付成功邏輯
				handlePaySuccess(order,openId);
			}
		} else if ("TRADE_CLOSED".equals(tradeStatus)) {
			// 未付款交易超時關閉,或支付完成後全額退款,執行相關業務邏輯
            //失敗 更改訂單狀態為支付失敗
			this.updatePayStatus(outTradeNo,PayStatusEnum.FAILUE.getCode(),openId);
		}
	}
	
複製程式碼

相關文章