停车服务扣费失败(TRANSACTION.FAIL)通知(JSON) 
商户请求微信支付分停车服务扣费受理接口,会完成订单受理。订单实际支付完成后,微信支付会把订单支付结果信息发送给商户,商户需要接收处理,并返回应答。
注意:
- 同样的通知可能会多次发送给商户系统。商户系统必须能够正确处理重复的通知。 推荐的做法是,当商户系统收到通知进行处理时,先检查对应业务数据的状态,并判断该通知是否已经处理。如果未处理,则再进行处理;如果已处理,则直接返回结果成功。在对业务数据进行状态检查和处理之前,要采用数据锁进行并发控制,以避免函数重入造成的数据混乱。
 - 如果在所有通知频率后没有收到微信侧回调,商户应调用查询订单接口确认订单状态。
 - 特别提醒:商户系统对于开启结果通知的内容一定要做签名验证,并校验通知的信息是否与商户侧的信息一致,防止数据泄露导致出现“假通知”,造成资金损失。
 - 用户支付完成后,微信会把相关支付结果和用户信息发送给商户,商户需要接收处理该消息,并返回应答。
 - 对后台通知交互时,如果微信收到商户的应答不符合规范或超时,微信认为通知失败,微信会通过一定的策略定期重新发起通知,尽可能提高通知的成功率,但微信不保证通知最终能成功。(通知频率为15s/15s/30s/3m/10m/20m/30m/30m/30m/60m/3h/3h/3h/6h/6h - 总计 24h4m)
 
| 请求参数 | 类型 | 描述 | 
|---|---|---|
| headers | object | 通知的头参数 | 
| Content-Type | string | application/json | 
| Request-ID | string | 通知的唯一标识 | 
| Wechatpay-Nonce | string | 数据签名使用的随机串 | 
| Wechatpay-Serial | string | 微信支付公钥ID/平台证书序列号 | 
| Wechatpay-Signature | string | 签名串 | 
| Wechatpay-Signature-Type | string | 签名算法WECHATPAY2-SHA256-RSA2048 枚举值 | 
| Wechatpay-Timestamp | string | 时间戳 | 
| body | object | 通知的JSON数据结构 | 
| id | string | 通知的唯一ID | 
| create_time | string | 通知创建的时间 | 
| event_type | string | 通知的类型TRANSACTION.FAIL 枚举值 | 
| resource_type | string | 通知的资源数据类型 | 
| summary | string | 回调摘要 | 
| resource | object | 通知资源数据 | 
| algorithm | string | 对数据进行加密的加密算法AEAD_AES_256_GCM 枚举值 | 
| associated_data | string | 数据加密的附加数据 | 
| nonce | string | 加密使用的随机串 | 
| ciphertext | string | 加密后的密文数据 | 
| original_type | string | 原始回调类型 | 
| sp_mchid | string | 调用接口提交的商户号 | 
| appid | string | 调用接口提交的应用ID | 
| sub_mchid | string | 调用接口提交的子商户号 | 
| sub_appid | string | 调用接口提交的子商户应用ID | 
| openid | string | 用户在服务商AppID下的唯一标识 | 
| sub_openid | string | 用户在子商户AppID下的唯一标识,如果是直连商户模式接入,该字段返回为空 | 
| plan_id | string | 签约模板号,签约模板唯一标识 | 
| contract_information | object | 签约信息 | 
| contract_id | string | 标识用户与某签约模板的一次签约,具有唯一性 | 
| contract_status | string | 枚举值: ADD:签约 DELETE:解约  | 
| create_time | string | 签约完成时间 | 
| out_trade_no | string | 调用接口提交的商户服务订单号 | 
| transaction_id | string | 微信支付系统生成的订单号 | 
| attach | string | 附加数据,在查询API和支付通知中原样返回,可作为自定义参数使用,实际情况下只有支付完成状态才会返回该字段。 | 
| bank_type | string | 银行类型,采用字符串类型的银行标识。 | 
| success_time | string | 订单支付完成时间 | 
| trade_state | string | 交易状态:SUCCESS:支付成功ACCEPT:已接收,等待扣款PAY_FAIL:支付失败(其他原因,如银行返回失败)REFUND:转入退款 | 
| trade_state_description | string | 对当前订单状态的描述和下一步操作的指引。 | 
| payer | object | 支付者信息,详细说明见下文 | 
| openid | string | 用户在服务商的标识 | 
| sub_openid | string | 用户在子商户的标识 | 
| sp_openid | string | 用户在服务商商户AppID下的唯一标识。 | 
| amount | object | 订单金额信息,详细说明见下文 | 
| currency | string | 符合ISO 4217标准的三位字母代码,目前只支持人民币:CNY | 
| payer_currency | string | 用户支付币种。 | 
| device_information | object | 设备信息 | 
| device_id | string | 商户设备号 | 
| payer_total | string | 商户端设备IP(发起扣款请求的商户服务器IP) | 
| promotion_detail | object[] | 优惠功能信息,详细说明见下文 | 
| coupon_id | string | 券或者立减优惠ID | 
| name | string | 优惠名称。 | 
| scope | string | 枚举值GLOBAL:全场代金券SINGLE:单品优惠 | 
| type | string | 枚举值:CASH:充值型代金券NOCASH:免充值型代金券 | 
| stock_id | string | 活动ID。 | 
| currency | string | CNY:人民币,境内商户号仅支持人民币。 | 
| goods_detail | object[] | 单品列表信息 | 
| goods_id | string | 商品编码。 | 
| quantity | number | 用户购买的数量。 | 
| unit_price | number | 商品单价,单位为分。 | 
| discount_amount | number | 商品优惠金额。 | 
| goods_remark | string | 商品备注信息。 | 
| activity_id | string | 在微信商户后台配置的批次ID。 | 
| mchid | string | 商户的商户号,由微信支付生成并下发。 | 
| trade_type | string | 交易类型PAP 枚举值 | 
| trade_state_desc | string | 交易状态描述。 | 
| scene_info | object | 支付场景信息描述 | 
| device_id | string | 终端设备号(门店号或收银设备ID)。 | 
| sp_appid | string | 服务商申请的公众号或移动应用AppID。 | 
| description | string | 商户自定义字段,用户交易账单中对扣费服务的描述。 | 
| create_time | string | 订单成功创建时返回 | 
| user_repaid | string | 枚举值:Y:用户已还款N:用户未还款注意:使用此字段前需先确认bank_type字段值为 BPA以及 trade_state字段值为SUCCESS。 | 
| trade_scene | string | 交易场景值,PARKING:车场停车场景 | 
| parking_info | object | trade_scene为PARKING时,返回停车场景信息 | 
| parking_id | string | 车主服务为商户分配的入场ID,商户通过入场通知接口获取入场ID | 
| plate_number | string | 车牌号,仅包括省份+车牌,不包括特殊字符。 | 
| plate_color | string | 车牌颜色BLUE | GREEN | YELLOW | BLACK | WHITE | LIMEGREEN 枚举值之一 | 
| start_time | string | 用户入场时间 | 
| end_time | string | 用户出场时间 | 
| parking_name | string | 所在停车位车场的名称 | 
| charging_duration | number | 计费的时间长,单位为秒 | 
| device_id | string | 停车场设备ID | 
停车服务(trade_scene)为固定值"PARKING"
保险商户委托代扣成功通知(trade_type)为"PAP"
php
// 使用Psr标准规范,示例如何处理(取值、验签、解密)「回调通知」事件,WebServer不同,用法略有差异,供参考实现。
function webhookProcessor(\Psr\Http\Message\RequestInterface $request,
  array $platformPublicKeyMap, string $apiv3Key): array {
  if (!\count($platformPublicKeyMap)) {
    throw new \WeChatPay\Exception\InvalidArgumentException('平台证书或者平台公钥数组不能为空');
  }
  if (\strlen($apiv3Key) !== 32) {
    throw new \WeChatPay\Exception\InvalidArgumentException('APIV3密钥为32字节,长度不对');
  }
  if (!($request->hasHeader(\WeChatPay\WechatpayNonce)
    && $request->hasHeader(\WeChatPay\WechatpaySerial)
    && $request->hasHeader(\WeChatPay\WechatpaySignature)
    && $request->hasHeader(\WeChatPay\WechatpayTimestamp))) {
    throw new \WeChatPay\Exception\InvalidArgumentException('通知的头参数缺失必要参数');
  }
  // 检查通知的时间偏移量,允许5分钟之内的偏移
  [$inWechatpayTimestamp] = $request->getHeader(\WeChatPay\WechatpayTimestamp);
  if (\WeChatPay\MAXIMUM_CLOCK_OFFSET < \abs(
    \WeChatPay\Formatter::timestamp() - (int)$inWechatpayTimestamp)) {
    throw new \WeChatPay\Exception\InvalidArgumentException('通知头参数的时间偏移量超过可信阈值');
  }
  // 检查通知的平台证书/平台公钥实例是否存在
  [$inWechatpaySerial] = $request->getHeader(\WeChatPay\WechatpaySerial);
  if (!\array_key_exists($inWechatpaySerial, $platformPublicKeyMap)) {
    throw new \WeChatPay\Exception\InvalidArgumentException('通知头参数的证书序列号/公钥ID本地不存在');
  }
  // 验证通知的数据签名
  [$inWechatpaySignature] = $request->getHeader(\WeChatPay\WechatpaySignature);
  [$inWechatpayNonce] = $request->getHeader(\WeChatPay\WechatpayNonce);
  $inBody = (string)$request->getBody();
  if (!\WeChatPay\Crypto\Rsa::verify(
    \WeChatPay\Formatter::joinedByLineFeed($inWechatpayTimestamp, $inWechatpayNonce, $inBody),
    $inWechatpaySignature, $platformPublicKeyMap[$inWechatpaySerial]
  )) {
    throw new \WeChatPay\Exception\InvalidArgumentException('通知头参数的数据签名校验未通过');
  }
  // 转换通知的JSON文本消息为PHP Array数组
  $inBodyArray = (array)\json_decode($inBody, true);
  // 使用PHP7+的数据解构语法,从Array中解构并赋值变量
  ['resource' => [
    'ciphertext'      => $ciphertext,
    'nonce'           => $nonce,
    'associated_data' => $aad
  ]] = $inBodyArray;
  // 加密文本消息解密,有可能解密异常(eg: 平台探测流量)会抛 \UnexpectedValueException
  $inBodyResource = \WeChatPay\Crypto\AesGcm::decrypt($ciphertext, $apiv3Key, $nonce, $aad);
  // 把解密后的文本转换为PHP Array数组
  $inBodyResourceArray = (array)\json_decode($inBodyResource, true);
  // 把解密后的数组定义为'original_data'函数返回
  $inBodyArray['resource']['original_data'] = $inBodyResourceArray;
  return [
    'headers' => $request->getHeaders(),
    'body' => $inBodyArray
  ];
}
// do your business
// ...
// ...
$json = \json_encode([
  'code' => 'SUCCESS',
  'message' => 'OK'
]);| 应答规范 | 类型 | 描述 | 
|---|---|---|
| status | number | HTTP状态码20X 4XX 5XX 枚举值之一 | 
| body | object | 应答的JSON数据结构 | 
| code | string | 业务处理状态码SUCCESS | FAIL 枚举值之一 | 
| message | string | 业务处理附加信息 | 
参阅 官方文档