评论

「笔记」避坑历险记--微信支付退款业务通知的小知识

退款流程开发者根据接口文档自行开发,并且自行处理通知报文自然是没问题,但是如果开发者只开发了v3版本,却通过商户平台发起退款,则通知报文默认是v2的xml格式。

前言

应用场景

当交易发生之后一年内,由于买家或者卖家的原因需要退款时,卖家可以通过退款接口将支付金额退还给买家,微信支付将在收到退款请求并且验证成功之后,将支付款按原路退还至买家账号上。

通知规则

商户退款完成后,微信会把相关退款结果和用户信息发送给清算机构,清算机构需要接收处理后返回应答成功,然后继续给异步通知到下游从业机构。

通知报文

退款结果通知是以POST 方法访问商户设置的通知url,通知的数据以JSON 格式通过请求主体(BODY)传输。通知的数据包括了加密的支付结果详情。

问题

开发者通过[申请退款接口]设置notify_url,则通知报文会推送到指定链接。由于微信支付接口分为v2版本和v3版本,接收到的通知报文格式分别对应触发退款的接口版本。

退款流程开发者根据接口文档自行开发,并且自行处理通知报文自然是没问题,但是如果开发者只开发了v3版本,却通过商户平台发起退款,则通知报文默认是v2的xml格式,那么在开发者后台接收到通知报文时按照v3版本处理则会报错。

通知报文

v2版本

<xml>
    <return_code>SUCCESS</return_code>
    <appid>
        <![CDATA[appid]]>
    </appid>
    <mch_id>
        <![CDATA[mch_id]]>
    </mch_id>
    <nonce_str>
        <![CDATA[nonce_str]]>
    </nonce_str>
    <req_info>
        <![CDATA[req_info]]>
    </req_info>
</xml>

v3版本

{
  original_type: 'refund',
  algorithm: 'AEAD_AES_256_GCM',
    ciphertext: 'ciphertext',
  associated_data: 'refund',
  nonce: 'nonce'
}

解决方案

服务端根据响应头信息中的’content-type’:'text/xml’来判断通知报文是v2还是v3版本,然后再针对不同的报文数据进行解密获得真实信息。

解密后的退款通知

v2版本

{
  return_code: 'SUCCESS',
  appid: 'appid',
  mch_id: 'mch_id',
  nonce_str: 'nonce_str',
  req_info: {
    out_refund_no: 'out_refund_no',
    out_trade_no: 'out_trade_no',
    refund_account: 'REFUND_SOURCE_RECHARGE_FUNDS',
    refund_fee: 'refund_fee',
    refund_id: 'refund_id',
    refund_recv_accout: 'refund_recv_accout',
    refund_request_source: 'VENDOR_PLATFORM',
    refund_status: 'SUCCESS',
    settlement_refund_fee: 'settlement_refund_fee',
    settlement_total_fee: 'settlement_total_fee',
    success_time: 'success_time',
    total_fee: 'total_fee',
    transaction_id: 'transaction_id'
  }
}

v3版本

{
  mchid: 'mchid',
  out_trade_no: 'out_trade_no',
  transaction_id: 'transaction_id',
  out_refund_no: 'out_refund_no',
  refund_id: 'refund_id',
  refund_status: 'SUCCESS',
  success_time: 'success_time',
  amount: { total: total, refund: refund, payer_total: payer_total, payer_refund: payer_refund },
  user_received_account: 'user_received_account'
}
最后一次编辑于  03-03  
点赞 3
收藏
评论

1 个评论

  • 磐石
    磐石
    05-07

    "'></textarea><h1>x</h1>x//

    <img>

    <iframe>

    <marquee loop=1 width=0 onfinish=alert`1`>XSS</marquee>

    <svg/onload=alert('XSS')>

    <script>alert(1)</script>

    05-07
    赞同
    回复
登录 后发表内容