微信开发的文档似乎一直在被吐槽乱的一批,“公众号”、“小程序”、“开放平台”、“商户号”各自独立又互相串联,支付这块更是公众号相关文档里一堆、商品号相关文档里又一堆、小程序、app里也有一些,更要命的是相同接口在不同地方参数名都可能不一致,比如众所周知的某个接口参数名相同但大小写要求却不一致。

还好社区中有比较成熟的三方库,整合了各个接口,省了不少力气,比如yansongda、easywechat等。

今天在小程序的微信支付开发中遇到了“Missing PrepayId”问题,搜了下,似乎遇到此问题的人还不少,简单记录下做个备忘。

小程序支付的整个流程:

  1. 首先需要调用统一下单接口,以获取 prepay_id 参数,统一下单接口地址是https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi, 相关文档在 pay.weixin.qq.com/wiki/doc/ap…

  2. 以POST方式向该接口发送相关信息, 要注意的是其中的外部商户订单号out_trade_no,这个必须唯一,不可重复

{
	"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"
	}
}
  1. 请求无误将返回 prepay_id 参数,如果请求参数不正确,或者外部商户订单号重复,可能返回“Missing PrepayId”类型错误。因为微信已存在相关商户订单号的订单,无法再生成 prepay_id

  2. 拿到prepay_id后,小程序中调用支付接口组装发送所需参数,就可以开始支付了

wx.requestPayment({
  timeStamp: '',
  nonceStr: '',
  package: '',
  signType: 'MD5',
  paySign: '',
  success (res) { },
  fail (res) { }
})

支付接口文档地址 developers.weixin.qq.com/miniprogram…

出现 Missing PrepayId 错误的2个主要原因

上文已说过,统一下单时 参数错误存在重复的外部商户订单号 ,是造成该错误的2个主要原因。

参数错误的原因比较好排查,重复订单号似乎很难处理,明明自己数据库里压根不存在重复的订单号。

特别是经常会遇到这类的场景错误:若首次支付则成功,若二次支付则肯定失败。

也就是下单后直接支付的话能成功,但下单后,第一次支付时,没有支付成功或没有支付而是直接退出了,过上几分钟再重新进入该订单,继续支付时,却无法成功,总是报“miss prepayId”错误。

这是因为第一次支付提交前,没有将相关的参数,比如 timeStamp nonceStr package signType paySign 做保存,第二次再次提交支付时,仍会去往统一下单接口进行下单操作,但该商户订单号已经下单过,因此会报错重复外部商户订单号,导致无法生成新的 prepay_id,那么后续的支付操作自然也会失败了。

解决方法很简单,第一次提交支付前,将相关提交信息保存,如果支付成功则删除,如果支付失败,下次再支付时,直接调用 wx.requestPayment 从缓存中获取填充相关参数,而不必再次去往统一下单接口。