微信商家转账新版的开发流程和常见问题

 引言

新的商家转账2025年1月15日正式上线,之前的商家转账到零钱和企业转账到零钱接口 基本不能使用了,本文章分享一下从旧零钱接口(已无法使用)到新的商家转账接口的改造和升级的方案

旧版接口调用后,会返回提示:

当前商户号接入升级版本功能,暂不支持使用升级前功能,请在产品中心-商家转账-前往功能查看接口文档。

同时鉴于关于商家转账的新版接口的文章比较少,特此出本文章,希望对大家有帮助,谢谢。

1.整体升级方案概述

1.1服务端发起转账的接口地址和body参数的改变,详见2接口区别

1.2新加了【转账场景报备信息】参数 新的商家转账对于不同的场景,需要提交不同的报备参数

报备参数官方文档:现金营销_商家转账|微信支付商户文档中心

1.3请求后返回内容和操作不同

以前的接口可以直接发起转账操作,用户可以直接收到零钱,无需用户操作。

新版接口,在返回值中存在package_info ,【跳转领取页面的package信息】。

然后需要用户进行在微信手机端手动进行领取

(后台发起API批准体现后,还需要通知用户领取转账)这就可能需要模板消息或者公众号客服消息、短信通知用户领取。

并且比较狗血的是,还需要我们来写APP或者JSapi的调起用户收款的接口和页面。

1.4需要在用户前端写调起用户领取的api

也就是下图的流程,下面详细讲解这个api的思路,仅写了jsapi的,本文暂时没有写app的调起

2.发起转账API接口的区别

2.1接口路径和body参数的变更

原路径:/v3/transfer/batches

现路径:/v3/fund-app/mch-transfer/transfer-bills

body变化:部分body参数的名称变化了,有一些参数不用了,具体可以看下官方的文档。

发起转账官方文档:发起转账_商家转账|微信支付商户文档中心

2.1.1API请求如下

header需要传递:Authorization 、Accept、Content-Type ,与旧版无变化。

 body参数:

”appid" : "wxf636efh567hg4356",

"out_bill_no" : "plfk2020042013", //与旧版相比,参数名称变了

"transfer_scene_id" : "1000", //新增的【转账场景ID】 

"openid" : "o-MYE42l80oelYMDE34nYD456Xoy",

"user_name" : "XXXX",//转账金额 >= 2,000元时,该笔明细必须填写

"transfer_amount" : 400000,

"transfer_remark" : "2020年4月报销",

"notify_url" : "https://www.weixin.qq.com/wxpay/pay.php",

"transfer_scene_report_infos" //新增的,【转账场景报备信息】 各转账场景下需报备的内容,商户需要按照所属转账场景规则传参。

curl -X POST \
https://api.mch.weixin.qq.com/v3/fund-app/mch-transfer/transfer-bills \
  -H "Authorization: WECHATPAY2-SHA256-RSA2048 mchid=\"1900000001\",..." \
  -H "Accept: application/json" \
  -H "Wechatpay-Serial: 5157F09EFDC096DE15EBE81A47057A7232F1B8E1"  \
  -H "Content-Type: application/json" \
  -d '{
    "appid" : "wxf636efh567hg4356",
    "out_bill_no" : "plfk2020042013",
    "transfer_scene_id" : "1000",
    "openid" : "o-MYE42l80oelYMDE34nYD456Xoy",
    "user_name" : "757b340b45ebef5467rter35gf464344v3542sdf4t6re4tb4f54ty45t4yyry45",
    "transfer_amount" : 400000,
    "transfer_remark" : "2020年4月报销",
    "notify_url" : "https://www.weixin.qq.com/wxpay/pay.php",
    "user_recv_perception" : "现金奖励",
    "transfer_scene_report_infos" : [
      {
        "info_type" : "活动名称",
        "info_content" : "新会员有礼"
       },
       {
        "info_type" : "奖励说明",
        "info_content" : "注册会员抽奖一等奖"
      }
    ]
  }'

2.1.2返回值

应答:200 OK

 返回参数:

{
  "out_bill_no" : "plfk2020042013",
  "transfer_bill_no" : "1330000071100999991182020050700019480001",
  "create_time" : "2015-05-20T13:29:35.120+08:00",
  "state" : "ACCEPTED",
  "fail_reason" : "PAYEE_ACCOUNT_ABNORMAL",
  "package_info" : "affffddafdfafddffda=="
}

需要注意的是,state是【单据状态】 商家转账订单状态,一般为:WAIT_USER_CONFIRM: 待收款用户确认,可拉起微信收款确认页面进行收款确认。

package_info 是【跳转领取页面的package信息】 跳转微信支付收款页的package信息,

用于调起用户收款的参数,前端页面需要传递package_info 后进行调起官方收款的接口。

因此,服务端需要保存package_info等相关发起转账成功的信息,并在用户端进行查询调用。

3.jsapi调起用户收款接口

jsapi调起收款官方文档:JSAPI调起用户确认收款_商家转账|微信支付商户文档中心

app调起收款文档:安卓:Android_商家转账|微信支付商户文档中心

                                iOS:iOS_商家转账|微信支付商户文档中心

前文,发起转账api成功后,会返回package_info,这时候就需要用了。

用户端(h5或小程序)需要新增确认收款页面,可以显示用户的提现信息,如下给大家作为参考。

用户端,新增确认收款页面vue

<template>
  <view class="cash-confirm" v-if="isLoad">
    <view class="fill-base pd-lg">
      <view class="flex-between">
        <view class="f-title c-title">提现金额</view>
        <view class="f-title">¥{{walletInfo.total_price}}</view>
      </view>
      <view class="flex-between mt-md">
        <view class="f-title c-title">手续费({{walletInfo.tax_point}}%)</view>
        <view class="f-title">¥{{walletInfo.service_price}}</view>
      </view>
      <view class="flex-between mt-md">
        <view class="f-title c-title">实际到账</view>
        <view class="f-title c-base" :style="{color: primaryColor}">¥{{walletInfo.apply_price}}</view>
      </view>
    </view>
    
    <view class="pd-lg mt-md fill-base">
      <view class="f-title c-title">到账方式</view>
      <view class="f-paragraph mt-md">微信零钱包</view>
    </view>

    <view class="pd-lg mt-md fill-base">
      <view class="f-title c-title">预计到账时间</view>
      <view class="f-paragraph mt-md">实时到账</view>
    </view>

    <view class="footer-btn">
      <view class="confirm-btn c-base flex-center" 
            :style="{background: primaryColor}"
             v-if="walletInfo.status == 2"
            @tap="confirmTransfer">
        确认提现
      </view>
      <view class="status-text f-title c-caption" v-else>
        {{statusType[walletInfo.status]}}
      </view>
    </view>
  </view>
</template>

<script>
import { mapState } from 'vuex'

export default {
  data() {
    return {
      isLoad: false,
      walletInfo: {},
      id: '',
      statusType: {
        1: '未到账',
        2: '已到账',
        3: '已拒绝'
      }
    }
  },
  computed: mapState({
    primaryColor: state => state.config.configInfo.primaryColor,
    subColor: state => state.config.configInfo.subColor,
  }),
  async onLoad(options) {
    this.id = options.id
    await this.initIndex()
    this.isLoad = true
  },
  methods: {
    async initIndex() {
      // 初始化微信JSSDK
      // #ifdef H5
      if (this.$jweixin.isWechat()) {
        await this.$jweixin.initJssdk()
        this.$jweixin.wxReady(() => {
          this.$jweixin.hideOptionMenu()
        })
      }
      // #endif
      
      await this.getWalletInfo()
    },
    
    // 获取提现详情
    async getWalletInfo() {
      try {
        this.$util.showLoading()
        this.walletInfo = await this.$api.mine.walletInfo({
          id: this.id
        })
        this.$util.hideAll()
      } catch (e) {
        this.$util.showToast({
          title: '获取提现信息失败'
        })
        setTimeout(() => {
          this.$util.goBack()
        }, 1500)
      }
    },

    // 确认提现
    async confirmTransfer() {
      if (!this.walletInfo.package_info) {
        this.$util.showToast({
          title: '获取支付参数失败'
        })
        return
      }

      // #ifdef H5
      if (this.$jweixin.isWechat()) {
        try {
          await this.$jweixin.requestPayment(this.walletInfo.package_info)
          this.$util.showToast({
            title: '提现成功'
          })
          setTimeout(() => {
            this.$util.goBack()
          }, 1500)
        } catch (e) {
          this.$util.showToast({
            title: '提现失败'
          })
        }
      }
      // #endif
    }
  }
}
</script>

<style lang="scss">
.cash-confirm {
  min-height: 100vh;
  background: #f5f5f5;
  
  .footer-btn {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    padding: 20rpx 30rpx;
    background: #fff;
    
    .confirm-btn {
      height: 88rpx;
      border-radius: 44rpx;
    }
  }
}
</style>

 jssdk中requestPayment函数,新增用户确认提现的函数

//用户确认提现收款
	async requestPayment(packageInfo) {
		return new Promise((resolve, reject) => {
			if (typeof WeixinJSBridge == "undefined") {
				reject("WeixinJSBridge not found")
				return
			}

			WeixinJSBridge.invoke(
				'requestMerchantTransfer', 
				{
					mchId: "微信支付商户号",
					appId: "公众号、小程序的appid",
					package: packageInfo, //从发起转账api中返回值获取的用户提现参数。
					
				},
				function(res) {
					if (res.err_msg === "requestMerchantTransfer:ok") {
						resolve(res)
					} else {
						reject(res.err_msg)
					}
				}
			)
		})
	},

 代码思路:

1.首先根据页面参数获取ID,根据ID请求服务端api,获取发起转账的信息package_info,

2.然后将package_info传递到用户端jssdk的package中,然后调起微信官方的收款接口即可。

4.通知用户收款的方式 

现在发起转账api成功后,还需要用户操作,所以需要在转账成功后通知用户,大家可以考虑微信公众号、小程序模板消息,短信通知等方式。

然后通过通知用户,让用户进去确认收款页面(并且传递提现id),进行收款即可完成,商家转账操作。

5.总结

以上就是老版本改新版的商家转账的方法和思路,希望对大家有帮助,如果需要技术支持可以联系我们哦!

我们是来自北京的软件开发公司,我是超凡,感谢大家的观看。

如有疑问欢迎评论,我将尽快解答和总结一期关于api的踩坑和解决方案。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值