在线不卡日本ⅴ一区v二区_精品一区二区中文字幕_天堂v在线视频_亚洲五月天婷婷中文网站

  • <menu id="lky3g"></menu>
  • <style id="lky3g"></style>
    <pre id="lky3g"><tt id="lky3g"></tt></pre>

    微信支付后端篇

    微信支付系列文章

    微信支付-java后端實(shí)現(xiàn)

    微信支付-vue 前端實(shí)現(xiàn)

    java demo: 下載地址文章底部

    技術(shù)棧

    Spring boot

    java

    XML (微信在http協(xié)議中數(shù)據(jù)傳輸方案)

    MD5 簽名

    微信支付術(shù)語

    openid (OpenID是公眾號一對一對應(yīng)用戶身份的標(biāo)識)

    app_id (公眾號id,登錄微信公眾號–開發(fā)–基本配置中獲得;)

    key (收款商戶后臺(tái)進(jìn)行配置,登錄微信商戶平臺(tái)–賬戶中心–API安全-設(shè)置秘鑰,設(shè)置32位key值;)

    mch_id (收款商家商戶號;)

    certPath (API證書, 登錄微信商戶平臺(tái)–賬戶中心-API安全-下載證書)

    后端流程

    服務(wù)端需要的核心操作, 總共分為以下幾步:

    統(tǒng)一下單

    前端調(diào)起微信支付必要參數(shù) (需加密)

    訂單結(jié)果主動(dòng)通知 (回調(diào)接口)

    查詢訂單結(jié)果

    結(jié)束訂單支付接口(關(guān)閉訂單,支付訂單關(guān)閉)

    代碼

    微信總共支持多種語言的sdk, 在官網(wǎng)可以下載例子, java程序也可以引入微信支付的sdk包, 但是github上的sdk已經(jīng)很久沒有更新了, 最好的選擇, 也是我的選擇, 在官網(wǎng)上下載sdk項(xiàng)目, 將其中所有java類copy到自己的項(xiàng)目中.

    官網(wǎng)sdk下載目錄

    鏈接: 商戶平臺(tái)首頁

    #### 根據(jù)微信sdk生成配置類 WXPayConfig

    創(chuàng)建IWxPayConfig.class, 繼承sdk WXPayConfig.class, 實(shí)現(xiàn)sdk中部分抽象方法, 讀取本地證書, 加載到配置類中.

    package core.com.chidori.wxpay;

    import core.com.wxpay.IWXPayDomain;

    import core.com.wxpay.WXPayConfig;

    import core.com.wxpay.WXPayConstants;

    import org.springframework.beans.factory.annotation.Value;

    import org.springframework.stereotype.Service;

    import java.io.ByteArrayInputStream;

    import java.io.File;

    import java.io.FileInputStream;

    import java.io.InputStream;

    @Service

    public class IWxPayConfig extends WXPayConfig { // 繼承sdk WXPayConfig 實(shí)現(xiàn)sdk中部分抽象方法

    private byte[] certData;

    @Value(“${vendor.wx.config.app_id}”)

    private String app_id;

    @Value(“${vendor.wx.pay.key}”)

    private String wx_pay_key;

    @Value(“${vendor.wx.pay.mch_id}”)

    private String wx_pay_mch_id;

    public IWxPayConfig() throws Exception { // 構(gòu)造方法讀取證書, 通過getCertStream 可以使sdk獲取到證書

    String certPath = “/data/config/chidori/apiclient_cert.p12”;

    File file = new File(certPath);

    InputStream certStream = new FileInputStream(file);

    this.certData = new byte[(int) file.length()];

    certStream.read(this.certData);

    certStream.close();

    }

    @Override

    public String getAppID() {

    return app_id;

    }

    @Override

    public String getMchID() {

    return wx_pay_mch_id;

    }

    @Override

    public String getKey() {

    return wx_pay_key;

    }

    @Override

    public InputStream getCertStream() {

    return new ByteArrayInputStream(this.certData);

    }

    @Override

    public IWXPayDomain getWXPayDomain() { // 這個(gè)方法需要這樣實(shí)現(xiàn), 否則無法正常初始化WXPay

    IWXPayDomain iwxPayDomain = new IWXPayDomain() {

    @Override

    public void report(String domain, long elapsedTimeMillis, Exception ex) {

    }

    @Override

    public DomainInfo getDomain(WXPayConfig config) {

    return new IWXPayDomain.DomainInfo(WXPayConstants.DOMAIN_API, true);

    }

    };

    return iwxPayDomain;

    }

    }

    發(fā)起統(tǒng)一下單 AND 前端調(diào)起微信支付必要參數(shù)

    // 發(fā)起微信支付

    WXPay wxpay = null;

    Map result = new HashMap();

    try {

    // ******************************************

    //

    // 統(tǒng)一下單

    //

    // ******************************************

    wxpay = new WXPay(iWxPayConfig); // *** 注入自己實(shí)現(xiàn)的微信配置類, 創(chuàng)建WXPay核心類, WXPay 包括統(tǒng)一下單接口

    Map data = new HashMap();

    data.put(“body”, “訂單詳情”);

    data.put(“out_trade_no”, transOrder.getGlobalOrderId()); // 訂單唯一編號, 不允許重復(fù)

    data.put(“total_fee”, String.valueOf(transOrder.getOrderAmount().multiply(new BigDecimal(100)).intValue())); // 訂單金額, 單位分

    data.put(“spbill_create_ip”, “192.168.31.166”); // 下單ip

    data.put(“openid”, openId); // 微信公眾號統(tǒng)一標(biāo)示openid

    data.put(“notify_url”, “http://wxlj.oopmind.com/payCallback”); // 訂單結(jié)果通知, 微信主動(dòng)回調(diào)此接口

    data.put(“trade_type”, “JSAPI”); // 固定填寫

    logger.info(“發(fā)起微信支付下單接口, request={}”, data);

    Map response = wxpay.unifiedOrder(data); // 微信sdk集成方法, 統(tǒng)一下單接口unifiedOrder, 此處請求 MD5加密 加密方式

    logger.info(“微信支付下單成功, 返回值 response={}”, response);

    String returnCode = response.get(“return_code”);

    if (!SUCCESS.equals(returnCode)) {

    return null;

    }

    String resultCode = response.get(“result_code”);

    if (!SUCCESS.equals(resultCode)) {

    return null;

    }

    String prepay_id = response.get(“prepay_id”);

    if (prepay_id == null) {

    return null;

    }

    // ******************************************

    //

    // 前端調(diào)起微信支付必要參數(shù)

    //

    // ******************************************

    String packages = “prepay_id=” + prepay_id;

    Map wxPayMap = new HashMap();

    wxPayMap.put(“appId”, iWxPayConfig.getAppID());

    wxPayMap.put(“timeStamp”, String.valueOf(Utility.getCurrentTimeStamp()));

    wxPayMap.put(“nonceStr”, Utility.generateUUID());

    wxPayMap.put(“package”, packages);

    wxPayMap.put(“signType”, “MD5”);

    // 加密串中包括 appId timeStamp nonceStr package signType 5個(gè)參數(shù), 通過sdk WXPayUtil類加密, 注意, 此處使用 MD5加密 方式

    String sign = WXPayUtil.generateSignature(wxPayMap, iWxPayConfig.getKey());

    // ******************************************

    //

    // 返回給前端調(diào)起微信支付的必要參數(shù)

    //

    // ******************************************

    result.put(“prepay_id”, prepay_id);

    result.put(“sign”, sign);

    result.putAll(wxPayMap);

    return result;

    } catch (Exception e) {

    }

    回調(diào)結(jié)果處理

    核心是支付訂單回調(diào)時(shí), 需校驗(yàn)加密簽名是否匹配, 防止出現(xiàn)模擬成功通知

    @RequestMapping(value = “/payCallback”, method = RequestMethod.POST)

    public String payCallback(HttpServletRequest request, HttpServletResponse response) {

    logger.info(“進(jìn)入微信支付異步通知”);

    String resXml=””;

    try{

    //

    InputStream is = request.getInputStream();

    //將InputStream轉(zhuǎn)換成String

    BufferedReader reader = new BufferedReader(new InputStreamReader(is));

    StringBuilder sb = new StringBuilder();

    String line = null;

    try {

    while ((line = reader.readLine()) != null) {

    sb.append(line + “”);

    }

    } catch (IOException e) {

    e.printStackTrace();

    } finally {

    try {

    is.close();

    } catch (IOException e) {

    e.printStackTrace();

    }

    }

    resXml=sb.toString();

    logger.info(“微信支付異步通知請求包: {}”, resXml);

    return wxTicketService.payBack(resXml);

    }catch (Exception e){

    logger.error(“微信支付回調(diào)通知失敗”,e);

    String result = “” + “” + “” + ” “;

    return result;

    }

    }

    @Override

    public String payBack(String notifyData) {

    logger.info(“payBack() start, notifyData={}”, notifyData);

    String xmlBack=””;

    Map notifyMap = null;

    try {

    WXPay wxpay = new WXPay(iWxPayConfig);

    notifyMap = WXPayUtil.xmlToMap(notifyData); // 轉(zhuǎn)換成map

    if (wxpay.isPayResultNotifySignatureValid(notifyMap)) {

    // 簽名正確

    // 進(jìn)行處理。

    // 注意特殊情況:訂單已經(jīng)退款,但收到了支付結(jié)果成功的通知,不應(yīng)把商戶側(cè)訂單狀態(tài)從退款改成支付成功

    String return_code = notifyMap.get(“return_code”);//狀態(tài)

    String out_trade_no = notifyMap.get(“out_trade_no”);//訂單號

    if (out_trade_no == null) {

    logger.info(“微信支付回調(diào)失敗訂單號: {}”, notifyMap);

    xmlBack = “” + “” + “” + ” “;

    return xmlBack;

    }

    // 業(yè)務(wù)邏輯處理 ****************************

    logger.info(“微信支付回調(diào)成功訂單號: {}”, notifyMap);

    xmlBack = “” + “” + “” + ” “;

    return xmlBack;

    } else {

    logger.error(“微信支付回調(diào)通知簽名錯(cuò)誤”);

    xmlBack = “” + “” + “” + ” “;

    return xmlBack;

    }

    } catch (Exception e) {

    logger.error(“微信支付回調(diào)通知失敗”,e);

    xmlBack = “” + “” + “” + ” “;

    }

    return xmlBack;

    }

    統(tǒng)一下單的簽名和后續(xù)前端拉取微信支付的簽名需要統(tǒng)一, 也就是都采用MD5加密, 如果2者不同, 會(huì)導(dǎo)致前端拉取微信支付fail, 這是一個(gè)巨大的坑, 因?yàn)檫@個(gè)原因調(diào)試了好久, 微信在文檔里沒有明確標(biāo)出統(tǒng)一下單的簽名校驗(yàn)方式 需要和前端拉取微信支付的簽名校驗(yàn)保持一致.

    微信sdk里的源碼需要針對這個(gè)問題調(diào)整一下, 調(diào)整如下:

    WXPay類需要修改下加密判斷,在WXPay構(gòu)造方法中,調(diào)整如下

    public WXPay(final WXPayConfig config, final String notifyUrl, final boolean autoReport, final boolean useSandbox) throws Exception {

    this.config = config;

    this.notifyUrl = notifyUrl;

    this.autoReport = autoReport;

    this.useSandbox = useSandbox;

    if (useSandbox) {

    this.signType = SignType.MD5; // 沙箱環(huán)境

    }

    else {

    this.signType = SignType.MD5; // 將這里的加密方式修改為SignType.MD5, 保持跟前端吊起微信加密方式保持一致

    }

    this.wxPayRequest = new WXPayRequest(config);

    }

    結(jié)束語

    做完以后, 微信支付的后端邏輯還是很清晰的, 但是在開發(fā)過程中很煎熬, 不清楚每個(gè)專業(yè)術(shù)語在微信哪里配置, 加密方式亂的很

    鄭重聲明:本文內(nèi)容及圖片均整理自互聯(lián)網(wǎng),不代表本站立場,版權(quán)歸原作者所有,如有侵權(quán)請聯(lián)系管理員(admin#wlmqw.com)刪除。
    用戶投稿
    上一篇 2022年7月4日 18:34
    下一篇 2022年7月4日 18:34

    相關(guān)推薦

    • 分享4條發(fā)微商朋友圈的方法(微商朋友圈應(yīng)該怎么發(fā))

      對于微商朋友來說,朋友圈的重要性不言而喻了。 那么微商的朋友圈到底該怎么發(fā)呢? 為什么同樣是經(jīng)營一個(gè)朋友圈,有的微商看起來逼格滿滿,實(shí)際效果也不錯(cuò);而有的卻動(dòng)都不動(dòng)就被屏蔽甚至拉黑…

      2022年11月27日
    • 淘寶工廠店的東西是正品嗎?淘寶工廠店為什么便宜

      淘工廠直營店其實(shí)就是鏈接淘寶賣家與工廠的平臺(tái),直接對接工廠型的商家,店鋪里的東西大部分價(jià)格都會(huì)很低。那么,淘工廠直營店靠譜嗎? 淘工廠直營店是靠譜的,但售后問題可能得不到很好的保障…

      2022年11月27日
    • 存儲(chǔ)過程語法(sql server存儲(chǔ)過程語法)

      今天小編給各位分享存儲(chǔ)過程語法的知識,其中也會(huì)對sql server存儲(chǔ)過程語法進(jìn)行解釋,如果能碰巧解決你現(xiàn)在面臨的問題,別忘了關(guān)注本站,現(xiàn)在開始吧! oracle存儲(chǔ)過程基本語法…

      2022年11月26日
    • 《寶可夢朱紫》夢特性怎么獲得?隱藏特性獲取方法推薦

      寶可夢朱紫里有很多寶可夢都是擁有夢特性會(huì)變強(qiáng)的寶可夢,很多玩家不知道夢特性怎么獲得,下面就給大家?guī)韺毧蓧糁熳想[藏特性獲取方法推薦,感興趣的小伙伴一起來看看吧,希望能幫助到大家。 …

      2022年11月25日
    • 《寶可夢朱紫》奇魯莉安怎么進(jìn)化?奇魯莉安進(jìn)化方法分享

      寶可夢朱紫中的奇魯莉安要怎么進(jìn)化呢?很多玩家都不知道,下面就給大家?guī)韺毧蓧糁熳掀骠斃虬策M(jìn)化方法分享,感興趣的小伙伴一起來看看吧,希望能幫助到大家。 奇魯莉安進(jìn)化方法分享 奇魯莉安…

      2022年11月25日
    • 數(shù)字看亮點(diǎn)!前十月我國造船三大指標(biāo)繼續(xù)全球領(lǐng)先

      央視網(wǎng)消息:工業(yè)和信息化部最新數(shù)據(jù)顯示,今年1—10月,我國造船三大指標(biāo)繼續(xù)保持全球領(lǐng)先。隨著生產(chǎn)節(jié)奏加快,船企產(chǎn)業(yè)集中度進(jìn)一步提升。 2022年1—10月,全國造船完工量、新接訂…

      2022年11月25日
    • 前十個(gè)月我國造船業(yè)三大指標(biāo)穩(wěn)居世界第一

      今年1—10月,我國造船業(yè)在國際市場的份額繼續(xù)穩(wěn)居世界第一。一批高技術(shù)高附加值船舶實(shí)現(xiàn)了批量接單、批量生產(chǎn)。 近日,中國船舶上海船舶研究設(shè)計(jì)院又新接了韓國船東三艘汽車運(yùn)輸船的設(shè)計(jì)追…

      2022年11月25日
    • 規(guī)范透明促PPP高質(zhì)量發(fā)展——16萬億元大市場迎來新規(guī)

      近日,財(cái)政部印發(fā)《關(guān)于進(jìn)一步推動(dòng)政府和社會(huì)資本合作(PPP)規(guī)范發(fā)展、陽光運(yùn)行的通知》,從做好項(xiàng)目前期論證、推動(dòng)項(xiàng)目規(guī)范運(yùn)作、嚴(yán)防隱性債務(wù)風(fēng)險(xiǎn)、保障項(xiàng)目陽光運(yùn)行四個(gè)方面進(jìn)一步規(guī)范P…

      2022年11月25日
    • 客服的崗位職責(zé)怎么寫(客服工作內(nèi)容及職責(zé))

      各位小伙伴們大家周一好,又到了每周一給大家分享干貨內(nèi)容的時(shí)候啦~ 本期來跟大家分享一下客服工作管理流程以及客服崗位里面的每項(xiàng)職能崗位的核心細(xì)則,也是干貨滿滿推薦收藏~ 一.補(bǔ)償流程…

      2022年11月25日
    • 商家收到貨才會(huì)退款嗎(淘寶代付款退款錢到哪里了)

      在淘寶上有一些人下單購買商品的時(shí)候是通過代付的形式來支付的,一般情況下是家長幫助家里的小孩或者長輩進(jìn)行代付,而代付訂單和普通的訂單沒有太大的區(qū)別,不過如果發(fā)生退款的話,錢是退到哪里…

      2022年11月25日

    聯(lián)系我們

    聯(lián)系郵箱:admin#wlmqw.com
    工作時(shí)間:周一至周五,10:30-18:30,節(jié)假日休息