国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

微信支付APIV3統(tǒng)一回調(diào)接口封裝(H5、JSAPI、App、小程序)

這篇具有很好參考價值的文章主要介紹了微信支付APIV3統(tǒng)一回調(diào)接口封裝(H5、JSAPI、App、小程序)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

?? @ 作者: 一恍過去
?? @ 主頁: https://blog.csdn.net/zhuocailing3390
?? @ 社區(qū): Java技術(shù)棧交流
?? @ 主題: 微信支付統(tǒng)一回調(diào)接口封裝(H5、JSAPI、App、小程序)
?? @ 創(chuàng)作時間: 2022年07月12日

微信支付回調(diào)接口,支付,微信,小程序

前言

對微信支付的H5、JSAPI、H5、App、小程序支付方式進(jìn)行統(tǒng)一,此封裝接口適用于普通商戶模式支付,如果要進(jìn)行服務(wù)商模式支付可以結(jié)合服務(wù)商官方API進(jìn)行參數(shù)修改(未驗證可行性)。

1、引入POM

        <!--微信支付SDK-->
        <dependency>
            <groupId>com.github.wechatpay-apiv3</groupId>
            <artifactId>wechatpay-apache-httpclient</artifactId>
            <version>0.4.7</version>
        </dependency>

2、配置Yaml

wxpay:
  #應(yīng)用編號
  appId: xxxx
  #商戶號
  mchId: xxx
  # APIv2密鑰
  apiKey: xxxx
  # APIv3密鑰
  apiV3Key: xxx
  # 微信支付V3-url前綴
  baseUrl: https://api.mch.weixin.qq.com/v3
  # 支付通知回調(diào), pjm6m9.natappfree.cc 為內(nèi)網(wǎng)穿透地址
  notifyUrl: http://pjm6m9.natappfree.cc/pay/payNotify
  # 退款通知回調(diào), pjm6m9.natappfree.cc 為內(nèi)網(wǎng)穿透地址
  refundNotifyUrl: http://pjm6m9.natappfree.cc/pay/refundNotify
  # 密鑰路徑,resources根目錄下
  keyPemPath: apiclient_key.pem
  #商戶證書序列號
  serialNo: xxxxx

3、配置密鑰文件

在商戶/服務(wù)商平臺的”賬戶中心" => “API安全” 進(jìn)行API證書、密鑰的設(shè)置,API證書主要用于獲取“商戶證書序列號”以及“p12”、“key.pem”、”cert.pem“證書文件,j將獲取的apiclient_key.pem文件放在項目的resources目錄下。
微信支付回調(diào)接口,支付,微信,小程序

4、配置PayConfig

WechatPayConfig:


import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
import com.wechat.pay.contrib.apache.httpclient.auth.Verifier;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Validator;
import com.wechat.pay.contrib.apache.httpclient.cert.CertificatesManager;
import com.wechat.pay.contrib.apache.httpclient.exception.HttpCodeException;
import com.wechat.pay.contrib.apache.httpclient.exception.NotFoundException;
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.impl.client.CloseableHttpClient;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.security.PrivateKey;

/**
 * @Author:
 * @Description:
 **/
@Component
@Data
@Slf4j
@ConfigurationProperties(prefix = "wxpay")
public class WechatPayConfig {
    /**
     * 應(yīng)用編號
     */
    private String appId;
    /**
     * 商戶號
     */
    private String mchId;
    /**
     * 服務(wù)商商戶號
     */
    private String slMchId;
    /**
     * APIv2密鑰
     */
    private String apiKey;
    /**
     * APIv3密鑰
     */
    private String apiV3Key;
    /**
     * 支付通知回調(diào)地址
     */
    private String notifyUrl;
    /**
     * 退款回調(diào)地址
     */
    private String refundNotifyUrl;

    /**
     * API 證書中的 key.pem
     */
    private String keyPemPath;

    /**
     * 商戶序列號
     */
    private String serialNo;

    /**
     * 微信支付V3-url前綴
     */
    private String baseUrl;

    /**
     * 獲取商戶的私鑰文件
     * @param keyPemPath
     * @return
     */
    public PrivateKey getPrivateKey(String keyPemPath){

            InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(keyPemPath);
            if(inputStream==null){
                throw new RuntimeException("私鑰文件不存在");
            }
            return PemUtil.loadPrivateKey(inputStream);
    }

    /**
     * 獲取證書管理器實例
     * @return
     */
    @Bean
    public  Verifier getVerifier() throws GeneralSecurityException, IOException, HttpCodeException, NotFoundException {

        log.info("獲取證書管理器實例");

        //獲取商戶私鑰
        PrivateKey privateKey = getPrivateKey(keyPemPath);

        //私鑰簽名對象
        PrivateKeySigner privateKeySigner = new PrivateKeySigner(serialNo, privateKey);

        //身份認(rèn)證對象
        WechatPay2Credentials wechatPay2Credentials = new WechatPay2Credentials(mchId, privateKeySigner);

        // 使用定時更新的簽名驗證器,不需要傳入證書
        CertificatesManager certificatesManager = CertificatesManager.getInstance();
        certificatesManager.putMerchant(mchId,wechatPay2Credentials,apiV3Key.getBytes(StandardCharsets.UTF_8));

        return certificatesManager.getVerifier(mchId);
    }


    /**
     * 獲取支付http請求對象
     * @param verifier
     * @return
     */
    @Bean(name = "wxPayClient")
    public CloseableHttpClient getWxPayClient(Verifier verifier)  {

        //獲取商戶私鑰
        PrivateKey privateKey = getPrivateKey(keyPemPath);

        WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
                .withMerchant(mchId, serialNo, privateKey)
                .withValidator(new WechatPay2Validator(verifier));

        // 通過WechatPayHttpClientBuilder構(gòu)造的HttpClient,會自動的處理簽名和驗簽,并進(jìn)行證書自動更新
        return builder.build();
    }

    /**
     * 獲取HttpClient,無需進(jìn)行應(yīng)答簽名驗證,跳過驗簽的流程
     */
    @Bean(name = "wxPayNoSignClient")
    public CloseableHttpClient getWxPayNoSignClient(){

        //獲取商戶私鑰
        PrivateKey privateKey = getPrivateKey(keyPemPath);

        //用于構(gòu)造HttpClient
        WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
                //設(shè)置商戶信息
                .withMerchant(mchId, serialNo, privateKey)
                //無需進(jìn)行簽名驗證、通過withValidator((response) -> true)實現(xiàn)
                .withValidator((response) -> true);

        // 通過WechatPayHttpClientBuilder構(gòu)造的HttpClient,會自動的處理簽名和驗簽,并進(jìn)行證書自動更新
        return builder.build();
    }
}

微信支付回調(diào)接口,支付,微信,小程序

6、回調(diào)校驗器

用于對微信支付成功后的回調(diào)數(shù)據(jù)進(jìn)行簽名驗證,保證數(shù)據(jù)的安全性與真實性。

WechatPayValidator:


import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.wechat.pay.contrib.apache.httpclient.auth.Verifier;
import com.wechat.pay.contrib.apache.httpclient.util.AesUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.util.EntityUtils;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.time.DateTimeException;
import java.time.Duration;
import java.time.Instant;
import java.util.Map;

import static com.wechat.pay.contrib.apache.httpclient.constant.WechatPayHttpHeaders.*;

/**
 * @Author: 
 * @Description:
 **/
@Slf4j
public class WechatPayValidator {
    /**
     * 應(yīng)答超時時間,單位為分鐘
     */
    private static final long RESPONSE_EXPIRED_MINUTES = 5;
    private final Verifier verifier;
    private final String requestId;
    private final String body;


    public WechatPayValidator(Verifier verifier, String requestId, String body) {
        this.verifier = verifier;
        this.requestId = requestId;
        this.body = body;
    }

    protected static IllegalArgumentException parameterError(String message, Object... args) {
        message = String.format(message, args);
        return new IllegalArgumentException("parameter error: " + message);
    }

    protected static IllegalArgumentException verifyFail(String message, Object... args) {
        message = String.format(message, args);
        return new IllegalArgumentException("signature verify fail: " + message);
    }

    public final boolean validate(HttpServletRequest request)  {
        try {
            //處理請求參數(shù)
            validateParameters(request);

            //構(gòu)造驗簽名串
            String message = buildMessage(request);

            String serial = request.getHeader(WECHAT_PAY_SERIAL);
            String signature = request.getHeader(WECHAT_PAY_SIGNATURE);

            //驗簽
            if (!verifier.verify(serial, message.getBytes(StandardCharsets.UTF_8), signature)) {
                throw verifyFail("serial=[%s] message=[%s] sign=[%s], request-id=[%s]",
                        serial, message, signature, requestId);
            }
        } catch (IllegalArgumentException e) {
            log.warn(e.getMessage());
            return false;
        }

        return true;
    }

    private  void validateParameters(HttpServletRequest request) {

        // NOTE: ensure HEADER_WECHAT_PAY_TIMESTAMP at last
        String[] headers = {WECHAT_PAY_SERIAL, WECHAT_PAY_SIGNATURE, WECHAT_PAY_NONCE, WECHAT_PAY_TIMESTAMP};

        String header = null;
        for (String headerName : headers) {
            header = request.getHeader(headerName);
            if (header == null) {
                throw parameterError("empty [%s], request-id=[%s]", headerName, requestId);
            }
        }

        //判斷請求是否過期
        String timestampStr = header;
        try {
            Instant responseTime = Instant.ofEpochSecond(Long.parseLong(timestampStr));
            // 拒絕過期請求
            if (Duration.between(responseTime, Instant.now()).abs().toMinutes() >= RESPONSE_EXPIRED_MINUTES) {
                throw parameterError("timestamp=[%s] expires, request-id=[%s]", timestampStr, requestId);
            }
        } catch (DateTimeException | NumberFormatException e) {
            throw parameterError("invalid timestamp=[%s], request-id=[%s]", timestampStr, requestId);
        }
    }

    private  String buildMessage(HttpServletRequest request)  {
        String timestamp = request.getHeader(WECHAT_PAY_TIMESTAMP);
        String nonce = request.getHeader(WECHAT_PAY_NONCE);
        return timestamp + "\n"
                + nonce + "\n"
                + body + "\n";
    }

    private  String getResponseBody(CloseableHttpResponse response) throws IOException {
        HttpEntity entity = response.getEntity();
        return (entity != null && entity.isRepeatable()) ? EntityUtils.toString(entity) : "";
    }

    /**
     * 對稱解密,異步通知的加密數(shù)據(jù)
     * @param resource 加密數(shù)據(jù)
     * @param apiV3Key apiV3密鑰
     * @param type 1-支付,2-退款
     * @return
     */
    public static  Map<String, Object> decryptFromResource(String resource,String apiV3Key,Integer type) {

        String msg = type==1?"支付成功":"退款成功";
        log.info(msg+",回調(diào)通知,密文解密");
        try {
        //通知數(shù)據(jù)
        Map<String, String> resourceMap = JSONObject.parseObject(resource, new TypeReference<Map<String, Object>>() {
        });
        //數(shù)據(jù)密文
        String ciphertext = resourceMap.get("ciphertext");
        //隨機(jī)串
        String nonce = resourceMap.get("nonce");
        //附加數(shù)據(jù)
        String associatedData = resourceMap.get("associated_data");

        log.info("密文: {}", ciphertext);
        AesUtil aesUtil = new AesUtil(apiV3Key.getBytes(StandardCharsets.UTF_8));
        String resourceStr = aesUtil.decryptToString(associatedData.getBytes(StandardCharsets.UTF_8),
                nonce.getBytes(StandardCharsets.UTF_8),
                ciphertext);

        log.info(msg+",回調(diào)通知,解密結(jié)果 : {}", resourceStr);
        return JSONObject.parseObject(resourceStr, new TypeReference<Map<String, Object>>(){});
    }catch (Exception e){
        throw new RuntimeException("回調(diào)參數(shù),解密失?。?);
        }
    }
}

7、回調(diào)Body內(nèi)容處理

HttpUtils:

public class HttpUtils {

    /**
     * 將通知參數(shù)轉(zhuǎn)化為字符串
     * @param request
     * @return
     */
    public static String readData(HttpServletRequest request) {
        BufferedReader br = null;
        try {
            StringBuilder result = new StringBuilder();
            br = request.getReader();
            for (String line; (line = br.readLine()) != null; ) {
                if (result.length() > 0) {
                    result.append("\n");
                }
                result.append(line);
            }
            return result.toString();
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

6、支付/退款回調(diào)通知

支付/退款回調(diào)通知:在進(jìn)行支付或退款操作后,支付平臺向商戶發(fā)送的異步通知,用于告知支付或退款的結(jié)果和相關(guān)信息。這種回調(diào)通知是實現(xiàn)支付系統(tǒng)與商戶系統(tǒng)之間數(shù)據(jù)同步和交互的重要方式。

支付/退款回調(diào)通知包含一些關(guān)鍵信息,如訂單號、交易金額、支付/退款狀態(tài)、支付平臺的交易流水號等。

在回調(diào)后,通過解析回調(diào)數(shù)據(jù),一定需要驗證簽名的合法性。

NotifyController:


import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.lhz.demo.pay.WechatPayConfig;
import com.lhz.demo.pay.WechatPayValidator;
import com.lhz.demo.utils.HttpUtils;
import com.wechat.pay.contrib.apache.httpclient.auth.Verifier;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.ReentrantLock;


/**
 * @Author: 
 * @Description:
 **/
@Api(tags = "回調(diào)接口(API3)")
@RestController
@Slf4j
public class NotifyController {

    @Resource
    private WechatPayConfig wechatPayConfig;

    @Resource
    private Verifier verifier;

    private final ReentrantLock lock = new ReentrantLock();

    @ApiOperation(value = "支付回調(diào)", notes = "支付回調(diào)")
    @ApiOperationSupport(order = 5)
    @PostMapping("/payNotify")
    public Map<String, String> payNotify(HttpServletRequest request, HttpServletResponse response) {
        log.info("支付回調(diào)");

        // 處理通知參數(shù)
        Map<String,Object> bodyMap = getNotifyBody(request);
        if(bodyMap==null){
            return falseMsg(response);
        }

        log.warn("=========== 在對業(yè)務(wù)數(shù)據(jù)進(jìn)行狀態(tài)檢查和處理之前,要采用數(shù)據(jù)鎖進(jìn)行并發(fā)控制,以避免函數(shù)重入造成的數(shù)據(jù)混亂 ===========");
        if(lock.tryLock()) {
            try {
                // 解密resource中的通知數(shù)據(jù)
                String resource = bodyMap.get("resource").toString();
                Map<String, Object> resourceMap = WechatPayValidator.decryptFromResource(resource, wechatPayConfig.getApiV3Key(),1);
                String orderNo = resourceMap.get("out_trade_no").toString();
                String transactionId = resourceMap.get("transaction_id").toString();

                // TODO 根據(jù)訂單號,做冪等處理,并且在對業(yè)務(wù)數(shù)據(jù)進(jìn)行狀態(tài)檢查和處理之前,要采用數(shù)據(jù)鎖進(jìn)行并發(fā)控制,以避免函數(shù)重入造成的數(shù)據(jù)混亂
                log.warn("=========== 根據(jù)訂單號,做冪等處理 ===========");
            } finally {
                //要主動釋放鎖
                lock.unlock();
            }
        }

        //成功應(yīng)答
        return trueMsg(response);
    }


    @ApiOperation(value = "退款回調(diào)", notes = "退款回調(diào)")
    @ApiOperationSupport(order = 5)
    @PostMapping("/refundNotify")
    public Map<String, String> refundNotify(HttpServletRequest request, HttpServletResponse response) {
        log.info("退款回調(diào)");

        // 處理通知參數(shù)
        Map<String,Object> bodyMap = getNotifyBody(request);
        if(bodyMap==null){
            return falseMsg(response);
        }

        log.warn("=========== 在對業(yè)務(wù)數(shù)據(jù)進(jìn)行狀態(tài)檢查和處理之前,要采用數(shù)據(jù)鎖進(jìn)行并發(fā)控制,以避免函數(shù)重入造成的數(shù)據(jù)混亂 ===========");
        if(lock.tryLock()) {
            try {
                // 解密resource中的通知數(shù)據(jù)
                String resource = bodyMap.get("resource").toString();
                Map<String, Object> resourceMap = WechatPayValidator.decryptFromResource(resource, wechatPayConfig.getApiV3Key(),2);
                String orderNo = resourceMap.get("out_trade_no").toString();
                String transactionId = resourceMap.get("transaction_id").toString();

                // TODO 根據(jù)訂單號,做冪等處理,并且在對業(yè)務(wù)數(shù)據(jù)進(jìn)行狀態(tài)檢查和處理之前,要采用數(shù)據(jù)鎖進(jìn)行并發(fā)控制,以避免函數(shù)重入造成的數(shù)據(jù)混亂

                log.warn("=========== 根據(jù)訂單號,做冪等處理 ===========");
            } finally {
                //要主動釋放鎖
                lock.unlock();
            }
        }

        //成功應(yīng)答
        return trueMsg(response);
    }

    private Map<String,Object> getNotifyBody(HttpServletRequest request){
        //處理通知參數(shù)
        String body = HttpUtils.readData(request);
        log.info("退款回調(diào)參數(shù):{}",body);

        // 轉(zhuǎn)換為Map
        Map<String, Object> bodyMap = JSONObject.parseObject(body, new TypeReference<Map<String, Object>>(){});
        // 微信的通知ID(通知的唯一ID)
        String notifyId = bodyMap.get("id").toString();

        // 驗證簽名信息
        WechatPayValidator wechatPayValidator
                = new WechatPayValidator(verifier, notifyId, body);
        if(!wechatPayValidator.validate(request)){

            log.error("通知驗簽失敗");
            return null;
        }
        log.info("通知驗簽成功");
        return bodyMap;
    }

    private Map<String, String> falseMsg(HttpServletResponse response){
        Map<String, String> resMap = new HashMap<>(8);
        //失敗應(yīng)答
        response.setStatus(500);
        resMap.put("code", "ERROR");
        resMap.put("message", "通知驗簽失敗");
        return resMap;
    }

    private Map<String, String> trueMsg(HttpServletResponse response){
        Map<String, String> resMap = new HashMap<>(8);
        //成功應(yīng)答
        response.setStatus(200);
        resMap.put("code", "SUCCESS");
        resMap.put("message", "成功");
        return resMap;
    }
}

微信支付回調(diào)接口,支付,微信,小程序文章來源地址http://www.zghlxwxcb.cn/news/detail-717500.html

到了這里,關(guān)于微信支付APIV3統(tǒng)一回調(diào)接口封裝(H5、JSAPI、App、小程序)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 微信支付,JSAPI支付,APP支付,H5支付,Native支付,小程序支付功能詳情以及回調(diào)處理

    微信支付,JSAPI支付,APP支付,H5支付,Native支付,小程序支付功能詳情以及回調(diào)處理

    支付wiki: https://pay.weixin.qq.com/wiki/doc/apiv3/index.shtml 支付api: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/index.shtml 開發(fā)工具包(SDK)下載: https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay6_0.shtml#part-1 1.1簡介 JSAPI支付是指商戶通過調(diào)用微信支付提供的JSAPI接口,在支付場景中調(diào)起微信支付模

    2023年04月18日
    瀏覽(32)
  • uniapp+java/springboot實現(xiàn)微信小程序APIV3支付功能

    uniapp+java/springboot實現(xiàn)微信小程序APIV3支付功能

    微信小程序的支付跟H5的支付和APP支付流程不一樣,本次只描述下小程序支付流程。 1.微信小程序賬號 文檔:小程序申請 小程序支付需要先認(rèn)證,如果你有已認(rèn)證的公眾號,也可以通過公眾號免費注冊認(rèn)證小程序。 一般300元,我是認(rèn)證的政府的免費。 然后登錄小程序,設(shè)置

    2023年04月19日
    瀏覽(30)
  • 微信支付apiV3異常:The corresponding provider for the merchant already exists

    異常信息 原因 這個錯誤是微信SDK拋出的,這是因為微信支付apiV3的RSAConfig重復(fù)build導(dǎo)致,即RSAConfig要保證是 單例 才不會導(dǎo)致報錯。 參數(shù)說明 mchId:商戶號 privateKey:商戶號密鑰 mchSerialNo:商戶證書號 apiV3Key:apiV3密鑰 建議 可以把商戶配置參數(shù)使用數(shù)據(jù)庫保存,服務(wù)啟動的時

    2024年02月11日
    瀏覽(114)
  • 【微信小程序】Java實現(xiàn)微信支付(小程序支付JSAPI-V3)java-sdk工具包(包含支付出現(xiàn)的多次回調(diào)的問題解析,接口冪等性)

    【微信小程序】Java實現(xiàn)微信支付(小程序支付JSAPI-V3)java-sdk工具包(包含支付出現(xiàn)的多次回調(diào)的問題解析,接口冪等性)

    ? ? ? 對于一個沒有寫過支付的小白,打開微信支付官方文檔時徹底懵逼 ,因為 微信支付文檔太過詳細(xì), 導(dǎo)致我無從下手,所以寫此文章,幫助第一次寫支付的小伙伴梳理一下。 一、流程分為三個接口:(這是前言,先看一遍,保持印象,方便理解代碼) 1、第一個接口:

    2024年01月16日
    瀏覽(28)
  • java對接微信支付:JSAPI支付成功之“微信回調(diào)”

    承接上一篇微信支付,現(xiàn)在簡單說一下 微信支付回調(diào) 目錄 一、支付回調(diào) 二、微信回調(diào)地址問題 1.本地/上線測試 2.控制器調(diào)用接口(代碼) 總結(jié) 當(dāng)用戶支付成功之后,支付平臺會向我們指定的服務(wù)器接口發(fā)送請求傳遞訂單支付狀態(tài)數(shù)據(jù) 如果你是再本地進(jìn)行測試,那就需要使用

    2024年02月12日
    瀏覽(30)
  • 微信的 h5 支付和 jsapi 支付

    微信的 h5 支付和 jsapi 支付

    申請地址: https://pay.weixin.qq.com/ 如果你還沒有微信商戶號,請點擊上面的鏈接進(jìn)行申請,如果已經(jīng)有了,可以跳過這一步 首先點擊 賬戶中心 ? API安全 ? 申請API證書 申請詳細(xì)步驟: https://kf.qq.com/faq/161222NneAJf161222U7fARv.html 首先點擊 賬戶中心 ? API安全 ? 設(shè)置APIv3密鑰 ?

    2024年02月13日
    瀏覽(16)
  • 〔支付接入〕微信的 h5 支付和 jsapi 支付

    〔支付接入〕微信的 h5 支付和 jsapi 支付

    申請地址: https://pay.weixin.qq.com/ 如果你還沒有微信商戶號,請點擊上面的鏈接進(jìn)行申請,如果已經(jīng)有了,可以跳過這一步 首先點擊 賬戶中心 ? API安全 ? 申請API證書 申請詳細(xì)步驟: https://kf.qq.com/faq/161222NneAJf161222U7fARv.html 首先點擊 賬戶中心 ? API安全 ? 設(shè)置APIv3密鑰 ?

    2024年02月13日
    瀏覽(53)
  • 微信支付 H5端 和小程序端 統(tǒng)一下單接口 4個JAVA源碼文件代碼

    微信支付 H5端 和小程序端 統(tǒng)一下單接口 4個JAVA源碼文件代碼

    首先來看看官方支付文檔的一些相關(guān)信息? 1、用戶在商戶側(cè)完成下單,使用微信支付進(jìn)行支付 2、由商戶后臺向微信支付發(fā)起下單請求(調(diào)用統(tǒng)一下單接口)注:交易類型trade_type=MWEB 3、統(tǒng)一下單接口返回支付相關(guān)參數(shù)給商戶后臺,如支付跳轉(zhuǎn)url(參數(shù)名“mweb_url”),商戶通

    2024年02月08日
    瀏覽(21)
  • 微信H5支付及通知回調(diào)

    1.在微信商戶平臺中進(jìn)行登錄并申請相關(guān)功能和配置 1.1微信商戶平臺https://pay.weixin.qq.com/index.php/core/home/loginreturn_url=%2F 登錄并配置,在商戶平臺上 - 產(chǎn)品中心 - 開通相關(guān)的產(chǎn)品,比如我這里使用的是 H5支付 1.2 然后配置相關(guān)的參數(shù) 2.1導(dǎo)入相關(guān)依賴 2.2 代碼編寫 2.3 編寫H5支付回調(diào)

    2024年02月12日
    瀏覽(23)
  • java對接微信支付:JSAPI支付(微信公眾號支付)

    java對接微信支付:JSAPI支付(微信公眾號支付)

    本文是【微信JSAPI支付】文章,主要講解商戶對接微信支付,簡潔版測試 文章目錄 一、JSAPI支付接入前準(zhǔn)備 二、代碼片段 1.引入Maven依賴 2.后端業(yè)務(wù)請求接口 3.前端調(diào)起支付請求方法 總結(jié) 1、JSAPI支付首先需要注冊、認(rèn)證一個公眾號(大概300塊一年) 微信公眾號注冊 2、申請成為

    2024年02月08日
    瀏覽(29)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包