WeChat.Pay.EventHandler (wechat v0.19.0)
View Source微信支付 回调通知处理器
注意
对后台通知交互时,如果微信收到应答不是成功或超时,微信认为通知失败,
微信会通过一定的策略定期重新发起通知,尽可能提高通知的成功率,但微信不保证通知最终能成功
同样的通知可能会多次发送给商户系统。商户系统必须能够正确处理重复的通知。
推荐的做法是,当商户系统收到通知进行处理时,先检查对应业务数据的状态,
并判断该通知是否已经处理。如果未处理,则再进行处理;如果已处理,则直接返回结果成功。
在对业务数据进行状态检查和处理之前,要采用数据锁进行并发控制,以避免函数重入造成的数据混乱。
如果在所有通知频率后没有收到微信侧回调。商户应调用查询订单接口确认订单状态。通知规则
用户支付完成后,微信会把相关支付结果和用户信息发送给商户,商户需要接收处理该消息,并返回应答。
对后台通知交互时,如果微信收到商户的应答不符合规范或超时,微信认为通知失败,微信会通过一定的策略定期重新发起通知,尽可能提高通知的成功率, 但微信不保证通知最终能成功。
通知频率为 15s/15s/30s/3m/10m/20m/30m/30m/30m/60m/3h/3h/3h/6h/6h - 总计 24h4m
Usage
For Plug
defmodule YourAppWeb.PayEventRouter do
  use Plug.Router
  plug :match
  plug :dispatch
  Code.ensure_compiled!(WechatPayDemo.PayClient)
  post "/api/pay/callback",
    to: WeChat.Pay.EventHandler,
    init_opts: [client: WxPay, event_handler: &YourModule.handle_event/3]
  match _, do: conn
endFor Phoenix
建议是定义一个上方的 PayEventRouter, 然后接入到 endpoint 中 plug Plug.Parsers 的上一行:
defmodule YourAppWeb.Endpoint do
  # ...
  plug Plug.RequestId
  plug Plug.Telemetry, event_prefix: [:phoenix, :endpoint]
  plug YourAppWeb.PayEventRouter # <<== add to here, before Plug.Parsers
  plug Plug.Parsers,
    parsers: [:urlencoded, :multipart, :json],
    pass: ["*/*"],
    json_decoder: Phoenix.json_library()
  plug Plug.MethodOverride
  plug Plug.Head
  plug Plug.Session, @session_options
  plug YourAppWeb.Router
  # ...
end 注意 , Plug.Parsers 会解析 body, 请确保此 plug 传入的 body 为 binary 格式, 否则将会导致验签失败
如果确认 body 未被解析, 亦可使用下面方式接入到 router 里面:
post "/wx/pay/event", WeChat.Pay.EventHandler,
  client: WxPay,
  event_handler: &YourModule.handle_event/3before phoenix 1.17:
forward "/wx/pay/event", WeChat.Pay.EventHandler,
  client: WxPay,
  event_handler: &YourModule.handle_event/3Options
Summary
Types
@type event_handler() :: (Pay.client(), Plug.Conn.t(), message :: map() -> event_handler_return())
事件处理回调函数
@type event_handler_return() :: :ok | :error | {:error, any()} | Plug.Conn.t()
事件处理回调返回值
返回值说明:
- :ok: 成功
- :error: 返回错误
- {:error, any}: 返回错误