近期公司的项目需要接入微信支付,中间遇到了很多的坑,记载下来,希望大家能引以为戒。
1、下载签名生成工具,安装在手机上,输入应用的包名,产生应用签名,在申请微信支付权限的时候要用。
注意这里有一个坑:手机端生成的签名,和平台的的签名一定要一致,如果不一致,需要修改平台的签名。
注意区分生成环境和测试环境,不同环境应用的签名是不一样的。产品上线的时候,一定要换成生成环境的签名。
2、申请微信支付权限
在微信开放平台申请到支付权限,申请到需要的账号,主要有
appid 微信分配的公众账号ID
MCH_ID 商户号 微信分配的公众账号ID
API_KEY API密钥,在商户平台设置
3、引入微信的sdk
在gradle中引入依赖
compile 'com.tencent.mm.opensdk:wechat-sdk-android-with-mta:+'
4、从商家服务器后台获取支付需要的参数
支付需要的所有参数,都需要从服务器后台获取,不能再客户端自己生成,这是为了安全。
NetApi.getWxPay(orderCode, "2", paymentAmount) .compose(RxHelper.applyLoading(DialogHelper.loading(this))) .subscribe({ res -> handleWxData(res.data!!) }, { it -> ToastUtils.showShort("${it.message}") })
5、发起微信支付
我是在handleWxData的方法中发起微信支付 ,所需的参数全部从后台服务器获取,代码如下
private fun handleWxData(data: WxPayModel) {
val orderCode = intent.getStringExtra(ExtraHelper.ORDER_CODE) ?: return ToastUtils.showShort(R.string.error_get_order_code_failed)
val payRecordId = data.payRecordId
// 在支付之前,如果应用没有注册到微信,应该先调用IWXsg.registerApp将应用注册到微信
val api = WXAPIFactory.createWXAPI(this, null)
api.registerApp(Constants.APP_ID)
Log.e("mls","appId的值>>>======" + data.payUrlOrData)
val json = JSONObject(data.payUrlOrData)
val payRunnable = Runnable {
val req = PayReq()
sp = getSharedPreferences("wxinfo", Context.MODE_PRIVATE)
val ed = sp.edit()
ed.putString("payRecordId",payRecordId)
ed.putString("orderCode",orderCode)
ed.putString("appChannel",data.appChannel)
ed.commit()
req.appId = json.getString("appid")
req.partnerId = json.getString("partnerid")
req.prepayId = json.getString("prepayid")
req.packageValue = json.getString("package")
req.nonceStr = json.getString("noncestr")
req.timeStamp = json.getString("timestamp")
req.sign = json.getString("sign")
api.sendReq(req)
}
val payThread = Thread(payRunnable)
payThread.start()
}
6、支付回调
回调的页面的包名是固定的,项目包名+wxapi+WXPayEntryActivity
class WXPayEntryActivity : Activity(), IWXAPIEventHandler { lateinit var sp: SharedPreferences private val disposables = CompositeDisposable() private var api: IWXAPI? = null public override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) api = WXAPIFactory.createWXAPI(this, Constants.APP_ID) api!!.handleIntent(intent, this) } override fun onNewIntent(intent: Intent) { super.onNewIntent(intent) setIntent(intent) api!!.handleIntent(intent, this) } override fun onResp(resp: BaseResp) { if (resp.type == ConstantsAPI.COMMAND_PAY_BY_WX) { if (resp.errCode == 0) { Log.e("java", "onResp1: " + resp.errCode) Toast.makeText(this, "支付成功", Toast.LENGTH_LONG).show() intent(ParamDef.INTENT_TO_ORDER_PAID) reBack(resp.errCode) } else { Log.e("java", "onResp: " + resp.errCode) Toast.makeText(this, "支付失败", Toast.LENGTH_LONG).show() reBack(resp.errCode) intent(ParamDef.INTENT_TO_ORDER_NO_PAID) } finish() } } private fun reBack(code: Int){ sp = getSharedPreferences("wxinfo", Context.MODE_PRIVATE) val payRecordId = null val orderCode = null val appChannel = null val d = NetApi.synchPayLog(code.toString(),sp.getString("payRecordId",payRecordId), sp.getString("orderCode",orderCode),"","app", sp.getString("appChannel",appChannel)) .compose(RxHelper.applyLoading(DialogHelper.loading(this@WXPayEntryActivity))) .subscribe({ }, { it -> ToastUtils.showShort("${it.message}") }) disposables.add(d) } fun intent(intentCode: Int){ val intent = Intent(this, MineOrdersListActivity::class.java) intent.putExtra(ExtraHelper.INTENT_ID,intentCode) startActivity(intent) finish() } override fun onReq(baseReq: BaseReq) { } }
注意支付的sign值从后台获取,一定要注意这个sign值是否正确。我就是被后台坑了,折腾了一天,都无法调起微信支付页面,页看不出哪里错了,最后我把验签放在了客户端,自己获取需要的各种参数,成功调起支付。一定要注意。