SpringBoot集成支付寶沙箱環境


最近在忙於做畢業設計,剛好用到支付寶充值功能,就過來寫個帖子。

1.到支付寶網站注冊賬號

官網:https://openhome.alipay.com/platform/developerIndex.htm

 

 2.點擊研發服務進入沙箱環境

配置RSA2,推薦使用支付寶提供的密匙工具。同步異步接口也可以不設置,下文會在java代碼中設置

這里異步調用接口需要公網可以訪問,如果經濟不允許的情況下可以使用花生殼內網穿透工具:

網址:https://hsk.oray.com/

我的個人配置:開通HTTP協議需要花費6元永久域名

 

 

 

 

 

 

 

 

 3.沙箱賬號

用於登錄沙箱版支付寶app測試

4.接入項目

創建一個配置類

 

/**
 * @author 碼農界的小學生
 * @description:阿里支付配置信息
 * @title: AliDevPayConfig
 * @projectName graduation-project
 * @description: TODO
 * @date 2020/4/23 19:06
 */
@Configuration
public class AliDevPayConfig implements Serializable {

// 這個是支付完成后的跳轉路徑 可以是一個頁面地址等
    public static String returnUrl = "http://www.graduation.com/#/addIncoming";
    //服務器異步通知頁面路徑  需http://格式的完整路徑,不能加?id=123這類自定義參數,必須外網可以正常訪問
// 這個是支付成功失敗以后的通知接口會返回相應的參數
    public static String notifyUrl = "http://3111h4q179.zicp.vip/cms/alipay/notify";

    /**支付寶分配給開發者的應用ID*/
    public static String aliPayAppId = "你的appid";
    /**
     * 商戶id
     */
    public static String uid = "2088102180918899";
    /**支付寶網關*/
    public static String aliPayGateWay = "https://openapi.alipaydev.com/gateway.do";
    public static  String mcloud_api_domain = "http://mcloudmonitor.com/gateway.do";
    /**私鑰*/
    public static String aliPayPrivateKey = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCtPPBOHRZyOPH2Qn4IAWmY+qrJaYSs5PZwRtAxm7oPcgChnacGr8uTZKtZtNFMwoI1RXqutWAWjMhVNHv9JcAdZbL7LsXO8AuP09YcFpGGXEWFoze3RGeN4Oiy1JhC21nkZONXn2RlmR44dHNLvH3p213MjR6omV16qG0SqFyCQ6m3DPVvXn+aclw+0vZPa6wvjKFn57WdgFrrwHSKMvuPoz5qW4Yv7wu4isXyOowczyfX0DERVvcdYdaIPUOEBEN6EcKbVq8/FC1zMq79REBU/iVtVjWunRe6FMq+jbzNsVvZdwm2FEG2hcnw+GmvZUMIstUf3dm3yZiMqULPCGf/AgMBAAECggEAdingx4czrkmFUTHdgVxlSMGCCMv+gWfTaJYEoDHWYX6jS5mbOgZi13CNKC0brj3mTqvLmKuClR8F7ohUIkHDnsmloYsvxY0adcpKevIx5PG/Qf4onMr9z1qfnotAKCoyUIU4RKYl9t7QLDXSBtDVGdRVUJbZWKrzhhyn+Vf5cafOyyQEgMAonAYqkLweZilyFO5TGlgLKJsKXhQjltZrPxVebQ9PowIz47NvQVOBya+WGTAkyN1Bri10ZLxr62VGhUjUGKcRL0qVxtaXpafARcW5HU1U/aJlkX9stHZwRlLsxdN5MV1DwlKInX9shYHOHheCsohlB7ZaZYmwrVulEQKBgQD1cmknrwkiYgocPq7NhQ89IddmWgduqkTE9FbaDXtM7YrvTIPGJDCE5d71R+sw8GG36M0OQxitdB72mbv6md+FxqmAtlD6d0L5V0mJfRErW4W48NhCI03XIWUcy3JrtqVF1N7qlB7D5IkW3DBqFVHf2iO97oMczhhsQsVnrH0VmwKBgQC0r7zyS6DwV1Pb8q3n1dmWD/wg4PuV35PC/uZ5CXiYWOcbaZZM1+3QQ56F/qZugwsb7aXbl7lL67hZ70GcQJPC8YBHebrBK9q/8C29TkPigzY0jWgM4rFbcb/raRKP3Oy1T4itIUH1/nuWwZT2AoT8lLRbLmeUeDCvg3GsbrhvbQKBgQCxhkvKOQ5pQPHBFhFGcsvf0l9CFzGy+BH/Rh6fXgrlTBYmGHhi0oAJT12gmKDiZ6q14vqVKzBpHEjc4bqVeb+yuUqV3sfZMHNPdrOobr4BVxPz/Lbdtz0wsWW5muiqQZNuW5XToshRtTT2RNH7mGn8d4FMeXt5VRNTEkRHRPm/qwKBgEXtGS+gCznYYhDmG110io+jwgyrZVI8Q4Aci+9dtfknttEKDOvSSSvnb2smAR0Vw+/cCesxDboPELpleLvS1hyEwANpXdgyc6cCeYEgz+7SnuC5tQH/nWnpXL/rWw6oDkeg7yEplNBx2zyd0Ftg4DysBByhmd6AoT7bnNuBwgkFAoGAVYXQYh+YgM5mKaagBZOWqwhkP4Pr8Oo44G5RaswP/O7R4ulgQ48BsaPifngek+tDTetX3nlZjogb1YtIEEJNJ1SSPsvEZGzR0cwgysp+wRjER5O+M2rvNWc3G+a4wM864eYuCq1n73xL9FqXYIJXjRlmLobejYiOqYa02bRIpQc=";
    /**支付寶公鑰 注意是支付寶公鑰 不是應用公鑰*/
    public static String aliPayPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAix4U83rjS6rT8w8njXFEU+SAYH/zCCRQc98PpUDEBBx3qY7CaJPL0QPETs1WyufqZYRSKbW0Ml9wTA/SXgOp3bJn5v78vhe2LSFtmr0gCyNJXtSDrz91XgR/oK3T5j0yy8NgOMBjdjnI2a6cpqrt3YXkc02hhJTfG+3o6f+gGw6wtU7CC0BTGoH//lk+prNerjeFQLZd7hB0ANlC5JdSfDBHtr/+gPcL7ap84nEJA1TSOCnQP8h2UYd5MAwqwyqitK3B9hEUCWI7Mp3VgI+CAGVXXnUzL74hUK26yrTczucX9bEPUUAyrlxWIUZ3OsX07KwpL1PLnKH/HYJStFG8TQIDAQAB";
    public static String FORMAT = "JSON";

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

    /**商戶生成簽名字符串所使用的簽名算法類型,目前支持RSA2和RSA,推薦使用RSA2*/
    public static String SIGN_TYPE = "RSA2";
}

 Controller:

 

/**
 * @author 碼農界的小學生
 * @description:
 * @title: PayController
 * @projectName graduation-project
 * @description: TODO
 * @date 2020/4/23 21:39
 */
@RequestMapping("/cms/alipay")
@RestController
public class PayController implements PayControllerApi {
    @Autowired
    private PayService payService;

    @Override
    @RequestMapping(value = "/pay")
    public String aliPay(@RequestParam("id")String id,
                         @RequestParam("type")String type,@RequestParam("money")String money) throws IOException {
        return payService.aliPay(id,type,money);
    }

    @Override
    @RequestMapping ("/notify")
    public void payNotice(HttpServletRequest request,HttpServletResponse response) throws Exception {
         payService.alipayNotify(request,response);
    }

}

 

 

 

Service:

 

/**
 * @author 碼農界的小學生
 * @description:調用支付寶接口業務邏輯
 * @title: PayService
 * @projectName graduation-project
 * @description: TODO
 * @date 2020/4/23 21:43
 */
@Service
public class PayService {
    @Autowired
    private OrderClient orderClient;
    @Autowired
    private OrderCollectionRepository orderCollectionRepository;
    @Autowired
    private SuperRepository superRepository;
    @Autowired
    private UserRoleRepository userRoleRepository;
    @Autowired
    private UserRepository userRepository;
    /**
     * 調用支付寶接口
     * @return
     */
    public String aliPay(String id,String type,String money) {
        //非法參數 拋出異常
        if(StringUtils.isEmpty(id) || StringUtils.isEmpty(type) || StringUtils.isEmpty(money)){
             ExceptionCast.cast(CommonCode.INVALID_PARAM);
        }
        //實例化客戶端(參數:網關地址、商戶appid、商戶私鑰、格式、編碼、支付寶公鑰、加密類型),為了取得預付訂單信息
        AlipayClient alipayClient = new DefaultAlipayClient(AliDevPayConfig.aliPayGateWay,AliDevPayConfig.aliPayAppId,
                AliDevPayConfig.aliPayPrivateKey,AliDevPayConfig.FORMAT,AliDevPayConfig.CHARSET,AliDevPayConfig.aliPayPublicKey,
                AliDevPayConfig.SIGN_TYPE);
        //實例化具體API對應的request類
        AlipayTradePagePayRequest payRequest = new AlipayTradePagePayRequest();
        payRequest.setNotifyUrl(AliDevPayConfig.notifyUrl);
        payRequest.setReturnUrl(AliDevPayConfig.returnUrl);
        //SDK已經封裝掉了公共參數,這里只需要傳入業務參數。以下方法為sdk的model入參方式
        AlipayTradePagePayModel payModel = new AlipayTradePagePayModel();
        //商戶訂單號
        UUID uuid = UUID.randomUUID();
        String uid = uuid.toString();
        payModel.setOutTradeNo(uid);
        //對一筆交易的具體描述信息。這里存儲用戶id
        payModel.setBody(id);
        //商品名稱
        payModel.setSubject(type);
        //交易超時時間 這里的30m就是30分鍾
        payModel.setTimeoutExpress("30m");
        //支付金額 后面保留2位小數點..不能超過2位
        payModel.setTotalAmount(money);
        // //電腦網站支付銷售產品碼,不同的支付方式productCode不同 銷售產品碼(固定值)
        payModel.setProductCode("FAST_INSTANT_TRADE_PAY");
        payRequest.setBizModel(payModel);
        try {
            // 這里和普通的接口調用不同,使用的是sdkExecute
            //返回支付寶訂單信息(預處理)
            AlipayTradePagePayResponse alipayTradePagePayResponse = alipayClient.pageExecute(payRequest);
            //就是orderString 可以直接給APP請求,無需再做處理。
            String result = alipayTradePagePayResponse.getBody();
            return result;
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 支付成功后接口回調 加上事務注解
     * @param request
     * @return
     */
    @Transactional
    public void alipayNotify(HttpServletRequest request, HttpServletResponse response) throws AlipayApiException, UnsupportedEncodingException {
        //獲取支付寶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] + ",";
            }
            //亂碼解決,這段代碼在出現亂碼時使用。
            //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put(name, valueStr);
        }
        //調用SDK簽名驗證
        //切記alipaypublickey是支付寶的公鑰,請去open.alipay.com對應應用下查看。
        //boolean AlipaySignature.rsaCheckV1(Map<String, String> params, String publicKey, String charset, String sign_type)
        boolean signVerified = AlipaySignature.rsaCheckV1(params, AliDevPayConfig.aliPayPublicKey, AliDevPayConfig.CHARSET,AliDevPayConfig.SIGN_TYPE);
        if(signVerified){
            //商戶訂單號
            String uid = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"),"UTF-8");
            //用戶id
            String userId = new String(request.getParameter("body").getBytes("ISO-8859-1"),"UTF-8");
            //健身房會員卡類型
            String type = new String(request.getParameter("subject").getBytes("ISO-8859-1"),"UTF-8");
            //金額
            String money = new String(request.getParameter("total_amount").getBytes("ISO-8859-1"),"UTF-8");
            /*
         這里編寫業務邏輯 
        */
} } }

 

 

 

 

5.項目調用支付寶接口流程

前端項目調用方法請求/cms/alipay/pay ,然后跳轉到支付頁面,支付完成后會同步跳轉returnUrl返回到商品頁面。支付寶支付后會異步請求notifyUrl,這里通過花生殼內網穿透工具代理到/cms/alipay/notify,然后完成業務邏輯。

6.效果圖

 

 

點擊會員充值調用對應的js方法:

submitPay(item){
                if (!this.params.id){
                    this.$message.error("請先登錄");
                    return ;
                }
                this.params.type = item.type;
                this.params.money = item.money;
                let querys = querystring.stringify(this.params);
                window.location ="http://www.graduation.com/cms/alipay/pay?"+querys;
            }

 

 

跳轉到支付頁面:

 

 

 

完成支付后自動跳轉到原來頁面:

 

哈哈,界面過於丑陋,咋們不要注重外表。前端頁面基本上都是自己一點一點組裝起來的,現在看到前端頭疼,索性丑就丑點吧。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM