https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=1_1
Discutamos el pago de WeChat con todos ~ (Para ser honesto, el sitio web oficial de WeChat es realmente un desastre, y cualquier similitud en las opiniones personales es pura coincidencia)
Las diversas descripciones de WeChat, los documentos no son lo suficientemente concisos y claros, y siento que están muy desordenados. Esto probablemente también sea un problema con el personal del equipo del producto.
El pago de Wechat ahora tiene 2 versiones, una es v2 v3, v3 es relativamente nueva
WeChat no tiene un entorno de espacio aislado, debe ser una empresa.
Primero, la plataforma comercial abre el pago de WeChat
El sistema comercial primero llama a esta interfaz para generar una orden de transacción de prepago en el fondo del servicio de pago de WeChat, devuelve el ID de sesión de transacción de prepago correcto y luego genera cadenas de transacción de acuerdo con diferentes escenarios, como Native, JSAPI y APP para iniciar el pago.
nombre del parámetro | variable | tipo [límite de longitud] | requerido | describir | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
ID de aplicación | appido | cadena[1,32] | Sí | ID de la aplicación del cuerpo generado por WeChat, único a nivel mundial. Preste atención al atributo de la aplicación APPID cuando solicite la interfaz de orden básica. Por ejemplo, en el escenario de la cuenta oficial, debe usar la cuenta de servicio APPID con el atributo de la aplicación como cuenta oficial. Valor de ejemplo: wxd678efh567hg6787 |
||||||||||||||||||||
Conectado directamente a la cuenta de comerciante | mchid | cadena[1,32] | Sí | body La cuenta de comerciante del comerciante conectado directamente, que WeChat Pay genera y entrega. Valor de ejemplo: 1230000109 |
||||||||||||||||||||
Descripción del Producto | descripción | cadena[1,127] | Sí | cuerpo Descripción del producto Valor de ejemplo: Tienda de imágenes-Muñeca Shenzhen Tengda-QQ |
||||||||||||||||||||
Número de pedido del comerciante | out_trade_no | cadena[6,32] | Sí | cuerpo El número de pedido interno del sistema comercial, que solo puede ser números, letras mayúsculas y minúsculas_-* y es único bajo el mismo número comercial. Valor de ejemplo: 1217752501201407033233368018 |
||||||||||||||||||||
Hora de finalización de la negociación | time_expire | cadena[1,64] | No | body El tiempo de vencimiento del pedido sigue el formato estándar rfc3339, el formato es aaaa-MM-DDTHH:mm:ss+TIMEZONE, yyyy-MM-DD representa el año, mes y día, T aparece en la cadena, representa el comienzo del elemento de tiempo, HH:mm:ss representa la hora, el minuto y el segundo, y TIMEZONE representa la zona horaria (+08:00 representa la hora del East Eighth District, que está 8 horas por delante de UTC, que es la hora de Pekín). Por ejemplo: 2015-05-20T13:29:35+08:00 significa 20 de mayo de 2015 13:29:35 hora de Beijing. Valor de ejemplo: 2018-06-08T10:34:56+08:00 |
||||||||||||||||||||
datos adicionales | adjuntar | cadena[1,128] | No | cuerpo Datos adicionales, que se devuelven tal como están en la API de consulta y la notificación de pago, y se pueden usar como un parámetro personalizado. En casos reales, este campo solo se devolverá cuando se complete el pago. Valor de ejemplo: datos personalizados |
||||||||||||||||||||
dirección de notificación | notificar_url | cadena[1,256] | Sí | body recibe de forma asíncrona la dirección de devolución de llamada de la notificación de resultado de pago de WeChat, la URL de notificación debe ser una URL accesible desde la red externa y no puede contener parámetros. El nombre de dominio de la red pública debe ser https. Si se accede a través de una línea dedicada, use la IP NAT de la línea privada o un nombre de dominio de devolución de llamada privado para usar el valor de ejemplo http: https://www.weixin.qq.com/wxpay/pay.php |
||||||||||||||||||||
Marca de descuento de pedido | etiqueta_bienes | cadena[1,32] | No | cuerpo Ficha de descuento de pedido Valor de ejemplo: WXG |
||||||||||||||||||||
Señal de apertura de entrada de factura electrónica | support_fapiao | booleano | No | Cuando el cuerpo se pasa como verdadero, el mensaje de éxito del pago y la página de detalles del pago mostrarán la entrada de facturación. La función de factura electrónica debe activarse en WeChat Pay Merchant Platform o WeChat Official Platform antes de pasar este campo para que surta efecto. verdadero: sí falso: no valor de ejemplo: verdadero |
||||||||||||||||||||
-Total de la orden | cantidad | objeto | Sí | información de la cantidad del orden del cuerpo | ||||||||||||||||||||
|
||||||||||||||||||||||||
- pagador | pagador | objeto | Sí | información del pagador del cuerpo | ||||||||||||||||||||
|
||||||||||||||||||||||||
-Función preferencial | detalle | objeto | No | función de descuento del cuerpo | ||||||||||||||||||||
|
||||||||||||||||||||||||
-场景信息 | 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版的微信支付了。
Pago de WeChat
La entrada de la interfaz de pago de WeChat es la misma que la de los productos de la plataforma pública de WeChat (cuenta oficial, programa pequeño y WeChat empresarial). Todos están unificados en el centro de recursos de la plataforma abierta de WeChat. De hecho, solo necesitamos visitar el sitio web oficial de la plataforma abierta de WeChat. A través del centro de recursos, podemos acceder a los documentos de interfaz de todos los productos de WeChat que necesitamos conectar.
Necesitamos solicitar muchos certificados.
Obtener devolución de llamada de pago de número de seguimiento prepago
@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;
}
}
}