https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=1_1
Discutons du paiement WeChat avec tout le monde ~ (Pour être honnête, le site officiel de WeChat est vraiment un gâchis, et toute similitude dans les opinions personnelles est purement fortuite)
Les différentes descriptions de WeChat, les documents ne sont pas assez concis et clairs, et j'ai l'impression qu'ils sont très brouillons, c'est probablement aussi un problème avec le personnel de l'équipe produit.
Le paiement Wechat a maintenant 2 versions, l'une est la v2 v3, la v3 est relativement nouvelle
WeChat n'a pas d'environnement sandbox, il doit être une entreprise.
Tout d'abord, la plateforme marchande ouvre le paiement WeChat
Le système marchand appelle d'abord cette interface pour générer une commande de transaction de prépaiement dans l'arrière-plan du service de paiement WeChat, renvoie l'ID de session de transaction de prépaiement correct, puis génère des chaînes de transaction selon différents scénarios tels que Native, JSAPI et APP pour initier le paiement.
le nom du paramètre | variable | tapez [longueur limite] | requis | décrire | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
ID d'application | appid | chaîne[1,32] | Oui | body App ID généré par WeChat, unique au monde. Veuillez prêter attention à l'attribut d'application APPID lors de la demande de l'interface de commande de base. Par exemple, dans le scénario de compte officiel, vous devez utiliser le compte de service APPID avec l'attribut d'application comme compte officiel Exemple de valeur : wxd678efh567hg6787 |
||||||||||||||||||||
Directement connecté au compte marchand | mchid | chaîne[1,32] | Oui | body Le compte marchand du marchand directement connecté, qui est généré et livré par WeChat Pay. Exemple de valeur : 1230000109 |
||||||||||||||||||||
Description du produit | description | chaîne[1,127] | Oui | corps Description du produit Exemple de valeur : Image store-Shenzhen Tengda-QQ poupée |
||||||||||||||||||||
Numéro de commande marchand | out_trade_no | chaîne[6,32] | Oui | body Le numéro de commande interne du système marchand, qui ne peut être composé que de chiffres, de lettres majuscules et minuscules_-* et qui est unique sous le même numéro de marchand Exemple de valeur : 1217752501201407033233368018 |
||||||||||||||||||||
Heure de fin de négociation | time_expire | chaîne[1,64] | Non | corps L'heure d'expiration de la commande suit le format standard rfc3339, le format est aaaa-MM-JJTHH:mm:ss+TIMEZONE, aaaa-MM-JJ représente l'année, le mois et le jour, T apparaît dans la chaîne, représentant le début de l'élément de temps, HH:mm:ss représente l'heure, la minute et la seconde, et TIMEZONE représente le fuseau horaire (+08:00 représente l'heure du Huitième District Est, qui est en avance de 8 heures sur UTC, qui est l'heure de Pékin). Par exemple : 2015-05-20T13:29:35+08:00 signifie 20 mai 2015 13:29:35 heure de Pékin. Exemple de valeur : 2018-06-08T10:34:56+08:00 |
||||||||||||||||||||
donnée supplémentaire | attacher | chaîne[1,128] | Non | body Données supplémentaires, qui sont renvoyées telles quelles dans l'API de requête et la notification de paiement, et peuvent être utilisées comme paramètre personnalisé. Dans les cas réels, ce champ ne sera renvoyé qu'une fois le paiement effectué. Exemple de valeur : données personnalisées |
||||||||||||||||||||
adresse de notification | notifier_url | chaîne[1,256] | Oui | body Reçoit de manière asynchrone l'adresse de rappel de la notification de résultat de paiement WeChat, l'url de notification doit être une url accessible depuis le réseau externe, et ne peut pas porter de paramètres. Le nom de domaine du réseau public doit être https. S'il est accessible via une ligne dédiée, utilisez l'IP NAT de la ligne privée ou un nom de domaine de rappel privé pour utiliser http Exemple de valeur : https://www.weixin.qq.com/wxpay/pay.php |
||||||||||||||||||||
Marque de remise de commande | marchandises_tag | chaîne[1,32] | Non | body Order discount token Exemple de valeur : WXG |
||||||||||||||||||||
Panneau d'ouverture de saisie de facture électronique | support_fapiao | booléen | Non | Lorsque le corps est passé à true, le message de réussite du paiement et la page des détails du paiement affichent l'entrée de facturation. La fonction de facture électronique doit être activée sur la plateforme marchande WeChat Pay ou la plateforme officielle WeChat avant de passer ce champ pour prendre effet. vrai : oui faux : non exemple de valeur : vrai |
||||||||||||||||||||
-montant de la commande | montant | objet | Oui | informations sur le montant de la commande de corps | ||||||||||||||||||||
|
||||||||||||||||||||||||
- payeur | payeur | objet | Oui | informations sur le payeur du corps | ||||||||||||||||||||
|
||||||||||||||||||||||||
-Fonction préférentielle | détail | objet | Non | fonction de réduction du corps | ||||||||||||||||||||
|
||||||||||||||||||||||||
-场景信息 | scene_info | object | 否 | body 支付场景描述 | ||||||||||||||||||||
|
||||||||||||||||||||||||
-结算信息 | settle_info | object | 否 | body 结算信息 | ||||||||||||||||||||
|
请求示例
{ "mchid": "1900006XXX", "out_trade_no": "1217752501201407033233368318", "appid": "wxdace645e0bc2cXXX", "description": "Image形象店-深圳腾大-QQ公仔", "notify_url": "https://www.weixin.qq.com/wxpay/pay.php", "amount": { "total": 1, "currency": "CNY" }, "payer": { "openid": "o4GgauInH_RCEdvrrNGrntXDuXXX" } }
返回参数
参数名 | 变量 | 类型[长度限制] | 必填 | 描述 |
---|---|---|---|---|
预支付交易会话标识 | prepay_id | string[1,64] | 是 | 预支付交易会话标识。用于后续接口调用中使用,该值有效期为2小时 示例值:wx201410272009395522657a690389285100 |
{ "prepay_id": "wx26112221580621e9b071c00d9e093b0000" }
错误码公共错误码
状态码 | 错误码 | 描述 | 解决方案 |
---|---|---|---|
403 | TRADE_ERROR | 交易错误 | 因业务原因交易失败,请查看接口返回的详细信息 |
500 | SYSTEM_ERROR | 系统错误 | 系统异常,请用相同参数重新调用 |
401 | SIGN_ERROR | 签名错误 | 请检查签名参数和方法是否都符合签名算法要求 |
403 | RULE_LIMIT | 业务规则限制 | 因业务规则限制请求频率,请查看接口返回的详细信息 |
400 | PARAM_ERROR | 参数错误 | 请根据接口返回的详细信息检查请求参数 |
403 | OUT_TRADE_NO_USED | 商户订单号重复 | 请核实商户订单号是否重复提交 |
404 | ORDER_NOT_EXIST | 订单不存在 | 请检查订单是否发起过交易 |
400 | ORDER_CLOSED | 订单已关闭 | 当前订单已关闭,请重新下单 |
500 | OPENID_MISMATCH | openid和appid不匹配 | 请确认openid和appid是否匹配 |
403 | NO_AUTH | 商户无权限 | 请商户前往申请此接口相关权限 |
400 | MCH_NOT_EXISTS | 商户号不存在 | 请检查商户号是否正确 |
500 | INVALID_TRANSACTIONID | 订单号非法 | 请检查微信支付订单号是否正确 |
400 | INVALID_REQUEST | 无效请求 | 请根据接口返回的详细信息检查 |
429 | FREQUENCY_LIMITED | 频率超限 | 请降低请求接口频率 |
500 | BANK_ERROR | 银行系统异常 | 银行系统异常,请用相同参数重新调用 |
400 | APPID_MCHID_NOT_MATCH | appid和mch_id不匹配 | 请确认appid和mch_id是否匹配 |
403 | ACCOUNT_ERROR | 账号异常 | 用户账号异常,无需更多操作 |
微信支付现在分为v2版和v3版
2014年9月10号之前申请的为v2版(旧版本),之后申请的为v3版。
V2版中的参数有
AppID
AppSecret
支付专用签名串PaySignKey
商户号PartnerID
初始密钥PartnerKey
并且包含一个证书文件: 安全证书
V3版中的参数有
AppID
AppSecret
商户号PartnerID
初始密钥PartnerKey
商户号MCHID
申请编号
商户平台登录帐号
商户平台登录密码
包含5个证书文件(证书pkcs12格式、证书pem格式、证书密钥pem格式、CA证书, 安全证书)
如果收到的邮件中没有【支付专用签名串PaySignKey】,表示已经是V3版的微信支付了。
Paiement WeChat
L'entrée de l'interface de paiement WeChat est la même que les produits de la plateforme publique WeChat (compte officiel, petit programme et entreprise WeChat). Ils sont tous unifiés dans le centre de ressources de la plateforme ouverte WeChat. En fait, nous n'avons qu'à visiter le site officiel de la plateforme ouverte WeChat. Grâce au centre de ressources, nous pouvons accéder aux documents d'interface de tous les produits WeChat dont nous avons besoin pour nous connecter.
Nous devons demander de nombreux certificats
Obtenez un rappel de paiement par numéro de suivi prépayé
@RestController
@Api(tags = "PayController")
@Tag(name = "PayController", description = "微信支付")
@RequestMapping("/v3")
public class PayController {
@PostMapping("/")
public Map createOrder(Long amount, String desc,String openId) throws Exception{
return PayUtil.createOrder(desc,amount,openId);
}
@PostMapping("/")
public Map callBackOrder(HttpServletRequest request) throws Exception{
System.out.println("微信回调开始返回");
System.out.println("Wechatpay-Timestamp:"+request.getHeader("Wechatpay-Timestamp"));
System.out.println("Wechatpay-Nonce:" + request.getHeader("Wechatpay-Nonce"));
System.out.println("Wechatpay-Signature:" + request.getHeader("Wechatpay-Signature"));
System.out.println("Wechatpay-Serial:" + request.getHeader("Wechatpay-Serial"));
Map result = new HashMap();
result.put("code","FAIL");
try {
StringBuilder signStr = new StringBuilder();
// 请求时间戳\n
signStr.append(request.getHeader("Wechatpay-Timestamp")).append("\n");
// 请求随机串\n
signStr.append(request.getHeader("Wechatpay-Nonce")).append("\n");
BufferedReader br = request.getReader();
String str =null;
StringBuilder builder =new StringBuilder();
while((str = br.readLine()) !=null){
builder.append(str);
}
System.out.println(builder);
signStr.append(builder.toString()).append("\n");
//验证签名
if(!PayUtil.signVerify(request.getHeader("Wechatpay-Serial"), signStr.toString(), request.getHeader("Wechatpay-Signature"))){
result.put("message","sign error");
return result;
}
//解密密文
String decryptOrder = PayUtil.decryptOrder(builder.toString());
System.out.println(decryptOrder);
//验证订单
result.put("message",decryptOrder);
result.put("code","SUCCESS");
}catch (IIOException e){
e.printStackTrace();
}
return result;
}
@PostMapping("/")
public Map<String, Object> wxPayNotify(HttpServletRequest request) {
System.out.println("微信回调开始返回");
System.out.println("Wechatpay-Timestamp:"+request.getHeader("Wechatpay-Timestamp"));
System.out.println("Wechatpay-Nonce:" + request.getHeader("Wechatpay-Nonce"));
System.out.println("Wechatpay-Signature:" + request.getHeader("Wechatpay-Signature"));
System.out.println("Wechatpay-Serial:" + request.getHeader("Wechatpay-Serial"));
Map result = new HashMap();
result.put("code", "FAIL");
BufferedReader reader = null;
try {
StringBuilder signStr = new StringBuilder();
// 请求时间戳\n
signStr.append(request.getHeader("Wechatpay-Timestamp")).append("\n");
// 请求随机串\n
signStr.append(request.getHeader("Wechatpay-Nonce")).append("\n");
// 请求报文主体\n
reader = request.getReader();
String str = null;
StringBuilder builder = new StringBuilder();
while ((str = reader.readLine()) != null) {
builder.append(str);
}
System.out.println(builder);
signStr.append(builder.toString()).append("\n");
// 1.验签
if (!V3WXPayUtil.signVerify(request.getHeader("Wechatpay-Serial"), signStr.toString(), request.getHeader("Wechatpay-Signature"))) {
result.put("message", "sign error");
return result;
}
// 2.解密
String decryptOrder = V3WXPayUtil.decryptOrder(builder.toString());
System.out.println(decryptOrder);
if (StringUtils.isEmpty(decryptOrder)) {
result.put("message", "verification error");
return result;
} else {
result.put("code", decryptOrder);
}
return result;
} catch (IOException e) {
e.printStackTrace();
result.put("code", "FAIL");
result.put("message", e.getMessage());
return result;
}
}
}