支付寶APP支付實現記錄

支付寶支付成功返回結果封裝

import com.alibaba.fastjson.annotation.JSONField;

import java.math.BigDecimal;
import java.util.Date;

/**
 * APP支付返回業務參數
 * @date 2018年1月24日
 */
public class AlipayAppPayRet{

	// 通知時間
	@JSONField(format="yyyy-MM-dd HH:mm:ss")
	private Date notify_time;
	// 通知類型
	private String notify_type;
	// 通知校驗ID
	private String notify_id;
	// 編碼格式
	private String charset;
	// 接口版本
	private String version;
	// 簽名類型
	private String sign_type;
	// 簽名
	private String sign;
	// 授權方的app_id
	private String auth_app_id;

	// 支付寶交易號
	private String trade_no;
	// 開發者的app_id
	private String app_id;
	// 商戶訂單號
	private String out_trade_no;
	// 商戶業務號
	private String out_biz_no;
	// 買家支付寶用戶號
	private String buyer_id;
	// 賣家支付寶用戶號
	private String seller_id;
	// 交易狀態
	private String trade_status;
	// 訂單金額
	private BigDecimal total_amount;
	// 實收金額
	private BigDecimal receipt_amount;
	// 開票金額
	private BigDecimal invoice_amount;
	// 付款金額
	private BigDecimal buyer_pay_amount;
	// 集分寶金額
	private BigDecimal point_amount;
	// 總退款金額
	private BigDecimal refund_fee;
	// 訂單標題
	private String subject;
	// 商品描述
	private String body;
	// 交易創建時間
	@JSONField(format="yyyy-MM-dd HH:mm:ss")
	private Date gmt_create;
	// 交易付款時間
	@JSONField(format="yyyy-MM-dd HH:mm:ss")
	private Date gmt_payment;
	// 交易退款時間
	@JSONField(format="yyyy-MM-dd HH:mm:ss")
	private Date gmt_refund;
	// 交易結束時間
	@JSONField(format="yyyy-MM-dd HH:mm:ss")
	private Date gmt_close;
	// 支付金額信息
	private String fund_bill_list;
	// 優惠券信息
	private String voucher_detail_list;
	/**
	 * 公共回傳參數,如果請求時傳遞了該參數,則返回給商戶時會在異步通知時將該參數原樣返回。 本參數必須進行UrlEncode之後纔可以發送給支付寶
	 */
	private String passback_params;

	public String getTrade_no() {
		return trade_no;
	}

	public void setTrade_no(String trade_no) {
		this.trade_no = trade_no;
	}

	public String getApp_id() {
		return app_id;
	}

	public void setApp_id(String app_id) {
		this.app_id = app_id;
	}

	public String getOut_trade_no() {
		return out_trade_no;
	}

	public void setOut_trade_no(String out_trade_no) {
		this.out_trade_no = out_trade_no;
	}

	public String getOut_biz_no() {
		return out_biz_no;
	}

	public void setOut_biz_no(String out_biz_no) {
		this.out_biz_no = out_biz_no;
	}

	public String getBuyer_id() {
		return buyer_id;
	}

	public void setBuyer_id(String buyer_id) {
		this.buyer_id = buyer_id;
	}

	public String getSeller_id() {
		return seller_id;
	}

	public void setSeller_id(String seller_id) {
		this.seller_id = seller_id;
	}

	public String getTrade_status() {
		return trade_status;
	}

	public void setTrade_status(String trade_status) {
		this.trade_status = trade_status;
	}

	public BigDecimal getTotal_amount() {
		return total_amount;
	}

	public void setTotal_amount(BigDecimal total_amount) {
		this.total_amount = total_amount;
	}

	public BigDecimal getReceipt_amount() {
		return receipt_amount;
	}

	public void setReceipt_amount(BigDecimal receipt_amount) {
		this.receipt_amount = receipt_amount;
	}

	public BigDecimal getInvoice_amount() {
		return invoice_amount;
	}

	public void setInvoice_amount(BigDecimal invoice_amount) {
		this.invoice_amount = invoice_amount;
	}

	public BigDecimal getBuyer_pay_amount() {
		return buyer_pay_amount;
	}

	public void setBuyer_pay_amount(BigDecimal buyer_pay_amount) {
		this.buyer_pay_amount = buyer_pay_amount;
	}

	public BigDecimal getPoint_amount() {
		return point_amount;
	}

	public void setPoint_amount(BigDecimal point_amount) {
		this.point_amount = point_amount;
	}

	public BigDecimal getRefund_fee() {
		return refund_fee;
	}

	public void setRefund_fee(BigDecimal refund_fee) {
		this.refund_fee = refund_fee;
	}

	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 Date getGmt_create() {
		return gmt_create;
	}

	public void setGmt_create(Date gmt_create) {
		this.gmt_create = gmt_create;
	}

	public Date getGmt_payment() {
		return gmt_payment;
	}

	public void setGmt_payment(Date gmt_payment) {
		this.gmt_payment = gmt_payment;
	}

	public Date getGmt_refund() {
		return gmt_refund;
	}

	public void setGmt_refund(Date gmt_refund) {
		this.gmt_refund = gmt_refund;
	}

	public Date getGmt_close() {
		return gmt_close;
	}

	public void setGmt_close(Date gmt_close) {
		this.gmt_close = gmt_close;
	}

	public String getFund_bill_list() {
		return fund_bill_list;
	}

	public void setFund_bill_list(String fund_bill_list) {
		this.fund_bill_list = fund_bill_list;
	}

	public String getVoucher_detail_list() {
		return voucher_detail_list;
	}

	public void setVoucher_detail_list(String voucher_detail_list) {
		this.voucher_detail_list = voucher_detail_list;
	}

	public String getPassback_params() {
		return passback_params;
	}

	public void setPassback_params(String passback_params) {
		this.passback_params = passback_params;
	}

	public Date getNotify_time() {
		return notify_time;
	}

	public void setNotify_time(Date notify_time) {
		this.notify_time = notify_time;
	}

	public String getNotify_type() {
		return notify_type;
	}

	public void setNotify_type(String notify_type) {
		this.notify_type = notify_type;
	}

	public String getNotify_id() {
		return notify_id;
	}

	public void setNotify_id(String notify_id) {
		this.notify_id = notify_id;
	}

	public String getCharset() {
		return charset;
	}

	public void setCharset(String charset) {
		this.charset = charset;
	}

	public String getVersion() {
		return version;
	}

	public void setVersion(String version) {
		this.version = version;
	}

	public String getSign_type() {
		return sign_type;
	}

	public void setSign_type(String sign_type) {
		this.sign_type = sign_type;
	}

	public String getSign() {
		return sign;
	}

	public void setSign(String sign) {
		this.sign = sign;
	}

	public String getAuth_app_id() {
		return auth_app_id;
	}

	public void setAuth_app_id(String auth_app_id) {
		this.auth_app_id = auth_app_id;
	}
}

下單和回調接口

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.AlipayConstants;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import plugins.pay.alipay.domain.AlipayAppPayRet;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.*;

@RestController
@Api(tags="支付接口")
@RequestMapping("/Indent")
public class H5IndentController {

    @GetMapping("/addAli")
    @ApiOperation(value = "支付寶新增訂單", notes = "支付寶新增訂單")
    public Map<String,Object> addWechat(HttpServletRequest request, HttpServletResponse response){

        //支付寶價格爲元,需要先處理價格(1800的單位是分)
        BigDecimal decimal = getBigDecimal(1800);

        //開始生成支付寶預支付
        String orderString;  //返回給app的字符串

        //創建支付寶APP支付的數據模型
        //注:此處用的支付寶官方的SDK,所以使用工具類填寫必填參數
        try {

            AlipayTradeAppPayModel model = getAppPayModel("天天樂", "會員充值",
                    "商戶訂單id", 30, decimal);

            //支付統一下單
            orderString = preOrder4App(model, "video");

            // TODO 保存數據

            // 返回結果
            HashMap<String, Object> map = new HashMap<>();
            map.put("orderString", orderString);
            map.put("indentId", "商戶訂單id");
            return map;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    // 支付寶收款回調
    @PostMapping("/aliNotify")
    public String aliNotify(HttpServletRequest request){
        //解析回調請求並驗籤
        try {

            AlipayAppPayRet ret = parseRequest(request, false);

            String tradeStatus = ret.getTrade_status();

            if(tradeStatus.equals("TRADE_SUCCESS")){

                // TODO 開始進行訂單處理,自行完善
                String result = updateIndent(ret.getOut_trade_no());

                System.out.println("----------------------------------------------------------------------交易完成!");
                return result;
            }else{
                System.out.println("支付狀態錯誤,交易狀態:" + tradeStatus);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        //應答支付寶
        return "success";

    }

    // 解析支付寶APP支付回調並驗籤
    public static AlipayAppPayRet parseRequest(HttpServletRequest request, boolean enc) throws Exception {
        return (AlipayAppPayRet) convertMap2Bean(getParamsMap(request.getParameterMap(), enc), AlipayAppPayRet.class);
    }

    // 將Map轉換成對象
    public static Object convertMap2Bean(Map<String, String> map, Class<?> clazz) throws Exception {
        Map<String, Object> objMap = new TreeMap<>();
        //預處理map,將裏面的json字符串字段轉換成對象
        Set<String> keys = map.keySet();
        for (String key : keys) {
            String str = map.get(key);
            try {
                //如果是JSON字符串,則轉換成對象,再添加到objMap中
                objMap.put(key, JSON.parse(str));
            } catch (JSONException e) {
                //如果不是JSON字符串,則直接添加到objMap中
                objMap.put(key, str);
            } catch (Exception e) {
                //其餘錯誤拋出
                e.printStackTrace();
            }
        }
        Object obj = JSON.parseObject(JSON.toJSONString(objMap), clazz);
        return obj;
    }

    // 驗籤並返回參數
    @SuppressWarnings("rawtypes")
    public static Map<String, String> getParamsMap(Map requestParamterMap, boolean enc) throws Exception {
        Map<String, String> params = new HashMap<>();

        for (Iterator iter = requestParamterMap.keySet().iterator(); iter.hasNext(); ) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParamterMap.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
            }
            if (enc) {
                valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            }
            params.put(name, valueStr);
        }

        // 切記alipaypublickey是支付寶的公鑰,請去open.alipay.com對應應用下查看。
        // boolean AlipaySignature.rsaCheckV1(Map<String, String> params, String
        // publicKey, String charset, String sign_type)
        boolean flag = AlipaySignature.rsaCheckV1(params, "支付寶公鑰", AlipayConstants.CHARSET_UTF8, "RSA2");
        if (!flag) {
            throw new RuntimeException("驗籤失敗");
        }
        return params;
    }

    // 支付寶生成APP訂單
    public static String preOrder4App(AlipayTradeAppPayModel model, String suffix) throws Exception {
        // 實例化客戶端
        AlipayClient alipayClient = new DefaultAlipayClient(
                // 支付地址
                "https://openapi.alipay.com/gateway.do",
                // 應用id
                "商戶APPID",
                // 私鑰
                "商戶私鑰",
                // 固定值json,參數類型,
                "json",
                // 編碼方式
                "UTF-8",
                // 公鑰
                "支付寶公鑰",
                // 簽名加密方式
                "RSA2");
        // 實例化具體API對應的request類,類名稱和接口名稱對應,當前調用接口名稱:alipay.trade.app.pay
        AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
        request.setBizModel(model);
        if (suffix == null || "".equals(suffix)) {
            throw new RuntimeException("回調地址後綴不能爲空");
        }
        request.setNotifyUrl("商戶後臺接口地址");
        try {
            // 這裏和普通的接口調用不同,使用的是sdkExecute
            AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
            return response.getBody();
        } catch (AlipayApiException e) {
            e.printStackTrace();
            throw e;
        }
    }

    // 處理金額
    public static BigDecimal getBigDecimal(int a){
        double b = a;
        b = b / 100;
        DecimalFormat df = new DecimalFormat("#.00");
        String s = df.format(b);
        BigDecimal f = new BigDecimal(s);
        return f;
    }

    /**
     * 設置必要的業務參數
     * @param body 商品描述
     * @param subject 商品的標題/交易標題/訂單標題/訂單關鍵字等
     * @param out_trade_no 商戶訂單號
     * @param timeout_express 有效時間,單位爲分鐘
     * @param total_account 價格,傳入帶兩位小數的數字 字符串,測試環境時爲固定值0.01
     * @return
     * @throws Exception
     */
    public static AlipayTradeAppPayModel getAppPayModel(String body, String subject, String out_trade_no,
                                                        int timeout_express, BigDecimal total_account) throws Exception {
        // SDK已經封裝掉了公共參數,這裏只需要傳入業務參數。以下方法爲sdk的model入參方式(model和biz_content同時存在的情況下取biz_content)。
        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
        model.setBody(body);
        model.setSubject(subject);
        model.setOutTradeNo(out_trade_no);
        model.setTimeoutExpress(timeout_express+"m");
        model.setTotalAmount(total_account.toString());
        model.setProductCode("QUICK_MSECURITY_PAY");
        return model;
    }
}

完成

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章