# wx.requestVirtualPayment(Object object)

> 基础库 2.19.2 开始支持，低版本需做[兼容处理](1003706)。

> __以 [Promise 风格](/miniprogram/dev/framework/app-service/api.md#异步-API-返回-Promise) 调用__：不支持
> 
> __小程序插件__：不支持

## 功能描述

发起米大师虚拟支付

## 参数

### Object object


```json
[
  {
    "属性": "signData",
    "类型": "Object",
    "默认值": "",
    "必填": "是",
    "说明": "具体支付参数见signData, 该参数需以string形式传递, 例如signData: '{\"offerId\":\"123\",\"buyQuantity\":1,\"env\":0,\"currencyType\":\"CNY\",\"productId\":\"testproductId\",\"goodsPrice\":10,\"outTradeNo\":\"xxxxxx\",\"attach\":\"testdata\"}'",
    "子项": [
      {
        "结构属性": "offerId",
        "类型": "string",
        "默认值": "",
        "必填": "是",
        "说明": "mp-支付基础配置中的offerid"
      },
      {
        "结构属性": "buyQuantity",
        "类型": "number",
        "默认值": "",
        "必填": "是",
        "说明": "购买数量"
      },
      {
        "结构属性": "env",
        "类型": "number",
        "默认值": "",
        "必填": "否",
        "说明": "环境配置, 0 正式环境, 1 沙箱环境, 默认为 0"
      },
      {
        "结构属性": "currencyType",
        "类型": "string",
        "默认值": "",
        "必填": "是",
        "说明": "币种",
        "子项": [
          {
            "合法值": "CNY",
            "说明": "人民币"
          }
        ]
      },
      {
        "结构属性": "productId",
        "类型": "string",
        "默认值": "",
        "必填": "否",
        "说明": "道具ID, **该字段仅mode=short_series_goods时需要必填**"
      },
      {
        "结构属性": "goodsPrice",
        "类型": "number",
        "默认值": "",
        "必填": "否",
        "说明": "道具单价(分), **该字段仅mode=short_series_goods时需要必填**, 用来校验价格与后台道具价格是否一致, 避免用户在业务商城页看到的价格与实际价格不一致导致投诉"
      },
      {
        "结构属性": "activitySellingPrice",
        "类型": "number",
        "默认值": "",
        "必填": "否",
        "说明": "道具优惠价格（分），**非必填，该字段需与goodsPrice一起传入**。如用户使用优惠券、积分等，需要以低于道具价格下单时可传入，传入后该价格即为实际下单价格。"
      },
      {
        "结构属性": "outTradeNo",
        "类型": "string",
        "默认值": "",
        "必填": "是",
        "说明": "业务订单号, 每个订单号只能使用一次, 重复使用会失败(极端情况不保证唯一, 不建议业务强依赖唯一性).  要求8-32个字符内, 只能是数字、大小写字母、符号 _-|*@组成, 不能以下划线(_)开头"
      },
      {
        "结构属性": "attach",
        "类型": "string",
        "默认值": "",
        "必填": "是",
        "说明": "透传数据, 发货通知时会透传给开发者"
      }
    ]
  },
  {
    "属性": "mode",
    "类型": "string",
    "默认值": "",
    "必填": "是",
    "说明": "支付的类型, 不同的支付类型有各自额外要传的附加参数",
    "子项": [
      {
        "合法值": "short_series_goods",
        "说明": "道具直购"
      },
      {
        "合法值": "short_series_coin",
        "说明": "代币充值"
      }
    ]
  },
  {
    "属性": "paySig",
    "类型": "string",
    "默认值": "",
    "必填": "是",
    "说明": "支付签名, 详见[《签名详解》](https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/industry/virtual-payment.html)"
  },
  {
    "属性": "signature",
    "类型": "string",
    "默认值": "",
    "必填": "是",
    "说明": "用户态签名, 详见[《签名详解》](https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/industry/virtual-payment.html)"
  },
  {
    "属性": "success",
    "类型": "function",
    "默认值": "",
    "必填": "否",
    "说明": "接口调用成功的回调函数"
  },
  {
    "属性": "fail",
    "类型": "function",
    "默认值": "",
    "必填": "否",
    "说明": "接口调用失败的回调函数"
  },
  {
    "属性": "complete",
    "类型": "function",
    "默认值": "",
    "必填": "否",
    "说明": "接口调用结束的回调函数（调用成功、失败都会执行）"
  }
]
```

#### object.success 回调函数
##### 参数

###### Object res

| 属性 | 类型 | 说明 |
| ---- | ---- | ---- |
| errMsg  | string | 调用成功信息 |

#### object.fail 回调函数
##### 参数

###### Object err

| 属性 | 类型 | 说明 |
| ---- | ---- | ---- |
| errMsg  | string | 错误信息 |
| errCode  | number | 错误码 |

## 错误
| 错误码 | 错误信息 | 说明 |
| -- | ---- | --- |
| 1001 |  | 参数错误 |
| -1 |  | 支付失败 |
| -2 |  | 支付取消 |
| -4 |  | 风控拦截 |
| -5 |  | 开通签约结果未知 |
| -15001 |  | 参数错误,具体原因见err_msg |
| -15002 |  | outTradeNo重复使用,请换新单号重试 |
| -15003 |  | 系统错误 |
| -15004 |  | currencyType错误,目前只能填CNY |
| -15005 |  | 用户态签名signature错误 |
| -15006 |  | 支付签名paySig错误 |
| -15007 |  | session_key过期 |
| -15008 |  | 二级商户进件未完成 |
| -15009 |  | 代币未发布 |
| -15010 |  | 道具productId未发布 |
| -15011 |  | 现网版本的env只能是0,不能填1(沙盒环境) |
| -15012 |  | 调用米大师失败导致关单,请换新单号重试 |
| -15013 |  | goodsPrice道具价格错误 |
| -15014 |  | 道具/代币发布未生效，禁止下单，大概10分钟后生效 |
| -15016 |  | signData格式有问题 |
| -15017 |  | 此商家涉嫌违规，收款功能已被限制，暂无法支付。商家可以登录微信商户平台/微信支付商家助手小程序查看原因和解决方案 |
| -15018 |  | 代币或者道具productId审核不通过 |
| -15019 |  | 调微信报商户受限,商家可以登录微信商户平台/微信支付商家助手小程序查看原因和解决方案 |
| -15020 |  | 操作过快，请稍候再试 |
| -15021 |  | 小程序被限频交易 |

## 注意事项：

- 1. 目前只有 >= v2.19.2 的基础库支持该接口，后续将对更多低版本基础库支持该接口。因此建议开发者这样判断：当前用户的基础库版本 >= v2.19.2 时可以直接用 wx.requestVirtualPayment，小于 v2.19.2 时，用 wx.canIUse('requestVirtualPayment') 来判断接口是否可用。具体判断方法可参考示例代码。

## 示例代码

```js
function compareVersion(_v1, _v2) {
  if (typeof _v1 !== 'string' || typeof _v2 !== 'string') return 0

  const v1 = _v1.split('.')
  const v2 = _v2.split('.')
  const len = Math.max(v1.length, v2.length)

  while (v1.length < len) {
    v1.push('0')
  }
  while (v2.length < len) {
    v2.push('0')
  }

  for (let i = 0; i < len; i++) {
    const num1 = parseInt(v1[i], 10)
    const num2 = parseInt(v2[i], 10)

    if (num1 > num2) {
      return 1
    } else if (num1 < num2) {
      return -1
    }
  }

  return 0
}

const SDKVersion = wx.getSystemInfoSync().SDKVersion

if (compareVersion(SDKVersion, '2.19.2') >= 0 || wx.canIUse('requestVirtualPayment')) {
  wx.requestVirtualPayment({
    signData: JSON.stringify({
      offerId: '123',
      buyQuantity: 1,
      env: 0,
      currencyType: 'CNY',
      productId: 'testproductId',
      goodsPrice: 10,
      outTradeNo: 'xxxxxx',
      attach: 'testdata',
    }),
    paySig: 'd0b8bbccbe109b11549bcfd6602b08711f46600965253a949cd6a2b895152f9d',
    signature: 'd0b8bbccbe109b11549bcfd6602b08711f46600965253a949cd6a2b895152f9d',
    mode: 'short_series_goods',
    success(res) {
      console.log('requestVirtualPayment success', res)
    },
    fail({ errMsg, errCode }) {
      console.error(errMsg, errCode)
    },
  })
} else {
  console.log('当前用户的客户端版本不支持 wx.requestVirtualPayment')
}
```
