unipay.md 45.3 KB
Newer Older
Q
qiang 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
## 简介

`unipay``uniCloud`开发者提供了简单、易用、统一的支付能力封装。让开发者无需研究支付宝、微信等支付平台的后端开发、无需为它们编写不同代码,拿来即用,屏蔽差异。

`uni-app`前端已经封装的全端支付 api `uni.requestPayment`,现在服务端也封装好了`unipay for uniCloud`,从此开发者可以极快的完成前后一体的支付业务。

目前已封装 App 端(微信支付和支付宝支付)、微信小程序、支付宝小程序的支付能力。

`unipay`是开源 sdk,可放心使用。本插件还包含示例工程,配置自己在微信和支付宝申请的相关配置后即可运行。

为了更好的体验支付流程可以在插件市场导入`unipay`的示例项目快速体验,[插件市场 unipay](https://ext.dcloud.net.cn/plugin?id=1835)

插件市场还有基于uniPay再次封装的模板,前端支付、管理端订单管理均已写好,拿去就用,见:[BaseCloud - 统一下单支付业务模块](https://ext.dcloud.net.cn/plugin?id=2668)

**须知**

- unipay 对入参和返回值均做了驼峰转化,开发者在对照微信支付或者支付宝支付对应的文档时需要注意。
- 特殊参数`appId``mchId`需注意大小写
- 所有金额被统一为以分为单位(避免浮点误差)
- 为避免无关参数干扰此文档仅列举必填参数,其余参数请参照[微信支付-小程序](https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_1)[微信支付-App](https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_1)[支付宝支付-小程序](https://opendocs.alipay.com/apis/api_1/alipay.trade.create)[支付宝支付-App](https://opendocs.alipay.com/apis/api_1/alipay.trade.app.pay)
- 微信支付沙箱环境不支持小程序支付,另外此沙箱环境只可以跑微信提供的测试用例不可以随意测试
- 无论是微信还是支付宝,沙箱环境都不确保稳定,如果使用沙箱的过程中遇到疑难问题建议切换成正式环境测试

**问题排查指引**

- [支付宝支付蚂蚁技术支持](https://openclub.alipay.com/club/history/read/7695)

## 引入 unipay

开发者可以自行选择是从插件市场导入还是从 npm 安装,引入方式略有不同,请看下面示例

```js
// 插件市场导入
const unipay = require('uni-pay')

// npm安装
const unipay = require('@dcloudio/unipay')
```

**注意**

- 插件市场导入的用法请参考[云函数公用模块](https://uniapp.dcloud.net.cn/uniCloud/cf-common)

## 初始化@init

进行初始化操作返回 unipay 实例
C
chenruilong 已提交
47 48
### 微信支付V3
> 新增于 ```uni-pay 1.1.0```
Q
qiang 已提交
49

C
chenruilong 已提交
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
**入参说明**

|        参数名	         |  类型		| 必填	 | 默认值												  |        说明											         |
|:-------------------:| :-----:	|:---:|:----------------:|:----------------------------:|
|       appId		       | String	| 是	  |  -													  |    当前应用在对应支付平台的 appId				    |
|       mchId		       | String	| 是	  |  -													  |        商户号										         |
|       v3Key		       | String	| 是	  |  -													  |     API v3 密钥										      |
|    appCertPath		    | String	| 是	  |  -													  |     商户 API 证书										      |
| appPrivateKeyPath		 | String	| 是	  |  -													  |     商户 API 私钥										      |
|      timeout	       | Number	| 否	  | 5000												 |      请求超时时间,单位:毫秒						      |

```js
const unipayIns = unipay.initWeixinV3({
  appId: 'your appId',
  mchId: 'your mchId',
  v3Key: 'you parterner key',
  appCertPath: path.resolve('/path/to/you/cert'),
  appPrivateKeyPath: path.resolve('/path/to/you/privateKey')
})
```
### 微信支付v2
Q
qiang 已提交
71 72 73

**入参说明**

C
chenruilong 已提交
74 75 76 77 78 79 80 81 82 83 84
|   参数名	    |  类型		|  必填	|  默认值												  |        说明											         |
|:---------:| :-----:	| :----:|:-----------------:|:----------------------------:|
|  appId		  | String	|   是	|  -													   |    当前应用在对应支付平台的 appId				    |
|  mchId		  | String	|   是	|  -													   |        商户号										         |
| subAppId  | String	|   否	|  -													   |       子商户appId								       |
| subMchId  | String	|   否	|  -													   |        子商户号									         |
|   key		   | String	|   是	|  -													   |     支付商户 key (API密钥)				     |
|   pfx		   | String|Buffer|                   使用退款功能必填|    -									     |    微信支付商户 API 证书,主要用于退款	     |
| timeout	  | Number	|   否	| 5000												  |      请求超时时间,单位:毫秒						      |
| signType	 | String	|   否	| MD5													  |        签名类型										        |
| sandbox	  | Boolean	|   否	| false												 |       是否启用沙箱环境								       |
Q
qiang 已提交
85 86 87 88 89 90

```js
const unipayIns = unipay.initWeixin({
  appId: 'your appId',
  mchId: 'your mchId',
  key: 'you parterner key',
雪洛's avatar
雪洛 已提交
91
  pfx: fs.readFileSync('/path/to/your/pfxfile'), // 建议以p12文件绝对路径进行读取,使用微信退款时需要
Q
qiang 已提交
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
})


// 以证书放在云函数index.js同级的cert目录下为例,index.js内可以按照下面这个写
const fs  = require('fs');  
const path = require('path');  
const unipayIns = unipay.initWeixin({
  appId: 'your appId',
  mchId: 'your mchId',
  key: 'you parterner key',
  pfx: fs.readFileSync(path.resolve(__dirname, 'cert/xxx.p12'))  
})
```

### 支付宝支付

**入参说明**

|     参数名						|  类型		| 必填|                        默认值												|                  说明									|
| :-------------:				| :-----:	| :--:| :--------------------------------------------------:| :------------------------------------:|
|   appId								| String	|  是	|                          -													|     当前应用在对应支付平台的 appId		|
|   mchId								| String	|   是|                          -													|                 商户号								|
|   privateKey					| String	|  是	|                          -													|             应用私钥字符串						|
| alipayPublicKey				| String	|  否	|                          -													|          支付宝公钥,验签使用					|
|     keyType						| String	|  否	|                        PKCS8												|           应用私钥字符串类型					|
|     timeout						| Number	|  否	|                         5000												|        请求超时时间,单位:毫秒				|
|    signType						| String	|  否	|                         RSA2												|                签名类型								|
|     sandbox						| Boolean	|  否	|                        false												|            是否启用沙箱环境						|
|   alipayRootCertPath	| String	|  否	| -																										| `1.0.6+`,支付宝根证书文件路径				|
|   appCertPath					| String	|  否	| -																										| `1.0.6+`,应用公钥证书文件路径				|
|   alipayPublicCertPath| String	|  否	| -																										| `1.0.6+`,支付宝公钥证书文件路径			|

```js
const unipayIns = unipay.initAlipay({
  appId: 'your appId',
  mchId: 'your mchId',
  privateKey: 'your privateKey',
  // 如果不使用证书(普通公钥模式)需要alipayPublicKey
  alipayPublicKey: 'you alipayPublicKey', // 使用支付时需传递此值做返回结果验签
  // 如果使用证书需要传alipayRootCertPath、appCertPath、alipayPublicCertPath
  alipayRootCertPath: path.join(__dirname,'../fixtures/alipayRootCert.crt'),
  appCertPath: path.join(__dirname,'../fixtures/appCertPublicKey.crt'),
  alipayPublicCertPath: path.join(__dirname,'../fixtures/alipayCertPublicKey_RSA2.crt'),
})
```

**常见问题**

- 支付宝支付时遇到`error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag`类似的错误时请确认一下自己的私钥格式,如果不是PKCS8需要在初始化时传入keyType参数,值为对应的私钥格式

J
jrptest 已提交
142

143
### 苹果内购支付
J
jrptest 已提交
144 145 146 147 148 149

**入参说明**

|     参数名						|  类型		| 必填|                        默认值												|                  说明									|
| :-------------:				| :-----:	| :--:| :--------------------------------------------------:| :------------------------------------:|
|     sandbox			    	| Boolean	|  否 |                       false							|            是否启用沙箱环境 			|
150
|     password		| String	|  否	|-				|  App 专用共享密钥,App 专用共享密钥是用于接收此 App 自动续期订阅收据的唯一代码。如果您要将此 App 转让给其他开发者或不想公开主共享密钥,建议使用 App 专用共享密钥。非自动续订场景不需要此参数|
J
jrptest 已提交
151
|     timeout			    	| Number	|  否 |                       5000							|      请求超时时间,单位:毫秒           |
J
jrptest 已提交
152

153

J
jrptest 已提交
154
```js
155
const unipayIns = unipay.initAppleIapPayment({
J
jrptest 已提交
156 157 158 159 160
  sandbox: true,
  password: 'your password',
})
```

Q
qiang 已提交
161 162 163 164 165 166 167 168
## Api 列表

### 获取支付参数

`unipayIns.getOrderInfo`,此接口仅支持微信小程序、支付宝小程序、App 平台

**入参说明**

雪洛's avatar
雪洛 已提交
169 170
|   参数名			|  类型	|                必填													| 默认值|                                    说明																																						|         支持平台				|
| :--------:		| :----:| :--------------------------------:					| :----:| :------------------------------------------------------------------------:																				| :----------------------:|
171
|   openid			| String|支付宝小程序、微信小程序必填,App端支付不需要|   -		|通过对应 [uni-id](uni-id-summary.md) 接口进行获取,服务商模式应使用子商户获取的openid															| 支付宝小程序、微信小程序|
雪洛's avatar
雪洛 已提交
172 173 174 175 176 177
|  subject			| String|支付宝支付必填,微信支付时忽略此项						|   -		|订单标题																																																						|        支付宝支付				|
|    body				| String|微信支付必填																	|   -		|商品描述																																																						|         微信支付				|
| outTradeNo		| String|必填																					|   -		|商户订单号,有长度限制(微信支付为32字符以内,支付宝为64字符以内)、只能包含字母、数字、下划线;需保证在商户端不重复|													|
|  totalFee			| Number|必填																					|   -		|订单金额,单位:分																																																	| 支付宝小程序、微信小程序|
| notifyUrl			| String|必填																					|   -		|支付结果通知地址,**需要注意支付宝支付时退款也会通知到此地址,务必处理好自己的业务逻辑**														|													|
| spbillCreateIp| String|必填																					|   -		|客户端IP,云函数内可以通过`context.CLIENTIP`获取																																		|-												|
C
chenruilong 已提交
178
|     tradeType	      | String	| 是	  |  -												   | 交易类型;见下方 tradeType 的说明						 |
雪洛's avatar
雪洛 已提交
179
| sceneInfo			| Object|微信tradeType为MWEB时必填										|   -		|见下方sceneInfo的说明																																															|-												|
雪洛's avatar
雪洛 已提交
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195

**tradeType的说明**

tradeType支持以下选项

- JSAPI 	适用于:微信公众号支付、微信小程序支付、支付宝小程序支付
- APP		适用于:支付宝、微信APP支付
- NATIVE	适用于:支付宝、微信PC网站扫码支付
- MWEB		适用于:微信h5(非公众号)跳转微信页面支付(`新增于uni-pay 1.0.24`

**sceneInfo的说明**

微信支付tradeType为MWEB时需要传递以下格式的sceneInfo

```js
{
雪洛's avatar
雪洛 已提交
196
	"h5Info": {
雪洛's avatar
雪洛 已提交
197
		"type": "Wap",
雪洛's avatar
雪洛 已提交
198 199
		"wapUrl": "https://pay.qq.com", // 开发者网站的网址
		"wapName": "腾讯充值" // 开发者网站名称
雪洛's avatar
雪洛 已提交
200 201 202
	}
}
```
Q
qiang 已提交
203 204 205 206 207 208 209

**返回值说明**

|  参数名   |  类型  |  说明  |                                支持平台                                |
| :-------: | :----: | :----: | :--------------------------------------------------------------------: |
| orderInfo | Object | String | 客户端支付所需参数,直接返回给客户端即可,下面会介绍如何搭配客户端使用 |

雪洛's avatar
雪洛 已提交
210

Q
qiang 已提交
211 212
**使用示例**

雪洛's avatar
雪洛 已提交
213 214 215 216
tradeType为NATIVE时直接将orderInfo.codeUrl转为二维码使用对应的客户端扫码支付即可

tradeType为MWEB时直接跳转到orderInfo.mwebUrl进行支付即可

Q
qiang 已提交
217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237
```js
// 云函数 - getOrderInfo
exports.main = async function (event,context) {
	let	orderInfo = await unipayIns.getOrderInfo({
		openid: 'user openid',
		subject: '订单标题', // 微信支付时不可填写此项
		body: '商品描述',
		outTradeNo: '商户订单号',
		totalFee: 1, // 金额,单位分
		notifyUrl: 'https://xxx.xx' // 支付结果通知地址
	})
	return {
		orderInfo
	}
}

// 客户端
uniCloud.callFunction({
	name: 'getOrderInfo',
	success(res) {
		uni.requestPayment({
238
			// #ifdef APP-PLUS
雪洛's avatar
雪洛 已提交
239 240 241 242 243
			provider: selectedProvider, // App端此参数必填,可以通过uni.getProvider获取
			// #endif
			// #ifdef MP-WEIXIN
			...res.result.orderInfo,
			// #endif
244
			// #ifdef APP-PLUS || MP-ALIPAY
雪洛's avatar
雪洛 已提交
245 246
			orderInfo: res.result.orderInfo,
			// #endif
Q
qiang 已提交
247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276
			...res.result.orderInfo
			success(){},
			fail(){}
		})
	}
})

// 二维码支付
uniCloud.callFunction({
	name: 'getOrderInfo',
	success(res) {
    // 以二维码形式展示此内容
		console.log(res.result.orderInfo.codeurl)
	}
})
```

### 查询订单

`unipayIns.orderQuery`, 根据商户订单号或者平台订单号查询订单信息,主要用于未接收到支付通知时可以使用此接口进行支付结果验证

**入参说明**

|    参数名     |  类型  |          必填           | 默认值 |    说明    | 支持平台 |
| :-----------: | :----: | :---------------------: | :----: | :--------: | :------: |
|  outTradeNo   | String | 和 transactionId 二选一 |   -    | 商户订单号 |     -     |
| transactionId | String |  和 outTradeNo 二选一   |   -    | 平台订单号 |     -     |

**返回值说明**

C
chenruilong 已提交
277 278 279 280 281 282 283 284 285 286
|       参数名			|  类型	|说明																																				|  支持平台   |
| :----------------:| :----:| :---------------------------------------------:														|:-------:|
|       appId				| String|平台分配的应用 ID																													|  微信支付   |
|       mchId				| String|商户号,(微信支付文档里面叫商户号:mch_id,支付宝支付叫卖家id:seller_id)|  微信支付   |
|     outTradeNo		| String|商户订单号																																	|   -		   |
|   transactionId		| String|平台订单号																																	|   -	    |
|     tradeState		| String| 订单状态,见下方订单状态说明																							|  					  |
|      totalFee			| Number|标价金额 ,单位:分																												|   -		   |
| settlementTotalFee| Number|应结订单金额,单位:分																											| 支付宝支付		 |
|      cashFee			| Number|现金支付金额,单位:分																											|   -		   |
雪洛's avatar
雪洛 已提交
287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305


**订单状态**

微信支付: 
SUCCESS—支付成功
REFUND—转入退款
NOTPAY—未支付
CLOSED—已关闭
REVOKED—已撤销(刷卡支付)
USERPAYING--用户支付中
PAYERROR--支付失败(其他原因,如银行返回失败)。

支付宝支付:
USERPAYING(交易创建,等待买家付款)
CLOSED(未付款交易超时关闭,或支付完成后全额退款)
SUCCESS(交易支付成功)
FINISHED(交易结束,不可退款)

Q
qiang 已提交
306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335

**使用示例**

```js
exports.main = async function (event) {
  let res = await unipayIns.orderQuery({
    outTradeNo: 'outTradeNo',
  })
  return res
}
```

### 关闭订单

`unipayIns.closeOrder`,用于交易创建后,用户在一定时间内未进行支付,可调用该接口直接将未付款的交易进行关闭,避免重复支付。

**注意**

- 微信支付:订单生成后不能马上调用关单接口,最短调用时间间隔为 5 分钟。

**入参说明**

|    参数名     |  类型  |                        必填                         | 默认值 |    说明    |  支持平台  |
| :-----------: | :----: | :-------------------------------------------------: | :----: | :--------: | :--------: |
|  outTradeNo   | String | 使用微信时必填,使用支付宝时和 transactionId 二选一 |   -    | 商户订单号 |      -      |
| transactionId | String |          使用支付宝时和 outTradeNo 二选一           |   -    | 平台订单号 | 支付宝支付 |

**返回值说明**

|    参数名     |  类型  |       说明        |  支持平台  |
C
chenruilong 已提交
336 337 338 339 340
| :-----------: | :----: | :---------------: |:------:|
|     appId     | String | 平台分配的应用 ID | 微信支付V2 |
|     mchId     | String |      商户号       | 微信支付V2 |
|  outTradeNo   | String |    商户订单号     | 支付宝支付  |
| transactionId | String |    平台订单号     | 支付宝支付  |
Q
qiang 已提交
341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395

**使用示例**

```js
exports.main = async function (event) {
  let res = await unipayIns.closeOrder({
    outTradeNo: 'outTradeNo',
  })
  return res
}
```

### 撤销订单

`unipayIns.cancelOrder`**此接口仅支付宝支持**,支付交易返回失败或支付系统超时,调用该接口撤销交易。如果此订单用户支付失败,支付宝系统会将此订单关闭;如果用户支付成功,支付宝系统会将此订单资金退还给用户。 注意:只有发生支付系统超时或者支付结果未知时可调用撤销,其他正常支付的单如需实现相同功能请调用申请退款 API。提交支付交易后调用【查询订单 API】,没有明确的支付结果再调用【撤销订单 API】。

**入参说明**

|    参数名     |  类型  |          必填           | 默认值 |    说明    |  支持平台  |
| :-----------: | :----: | :---------------------: | :----: | :--------: | :--------: |
|  outTradeNo   | String | 和 transactionId 二选一 |   -    | 商户订单号 | 支付宝支付 |
| transactionId | String |  和 outTradeNo 二选一   |   -    | 平台订单号 | 支付宝支付 |

**返回值说明**

|    参数名     |  类型  |    说明    |  支持平台  |
| :-----------: | :----: | :--------: | :--------: |
|  outTradeNo   | String | 商户订单号 | 支付宝支付 |
| transactionId | String | 平台订单号 | 支付宝支付 |

**使用示例**

```js
exports.main = async function (event) {
  let res = await unipayIns.cancelOrder({
    outTradeNo: 'outTradeNo',
  })
  return res
}
```

### 申请退款

`unipayIns.refund`,当交易发生之后一段时间内,由于买家或者卖家的原因需要退款时,卖家可以通过退款接口将支付款退还给买家。

**微信支付注意事项**

1. 交易时间超过一年的订单无法提交退款
2. 微信支付退款支持单笔交易分多次退款,多次退款需要提交原支付订单的商户订单号和设置不同的退款单号。申请退款总金额不能超过订单金额。 一笔退款失败后重新提交,请不要更换退款单号,请使用原商户退款单号
3. 请求频率限制:150qps,即每秒钟正常的申请退款请求次数不超过 150 次,错误或无效请求频率限制:6qps,即每秒钟异常或错误的退款申请请求不超过 6 次
4. 每个支付订单的部分退款次数不能超过 50 次
5. 如果同一个用户有多笔退款,建议分不同批次进行退款,避免并发退款导致退款失败

**入参说明**

C
chenruilong 已提交
396 397 398 399 400 401 402 403 404 405
|    参数名		|  类型	|        必填				         | 默认值|     说明											| 支持平台	  |
| :-----------:	| :----:|:---------------------:| :----:| :----------:										|:------:|
|  outTradeNo	| String| 和 transactionId 二选一		 |   -	|  商户订单号										|  -		   |
| transactionId	| String|  和 outTradeNo 二选一		   |   -	|  平台订单号										|  -		   |
|  outRefundNo	| String|    微信支付必填,支付宝支付选填	    |   -	| 商户退款单号										|   -	   |
|   totalFee	| Number|       微信支付必填			       |   -	|  订单总金额										|  -			  |
|   refundFee	| Number|        必填				         |   -	|  退款总金额										| 微信支付	  |
| refundFeeType	| String|     微信支付V3必填				      |   -	|   货币种类										|   微信支付V3		   |
|  refundDesc	| String|        选填				         |   -	|   退款原因										|  -		   |
|   notifyUrl	| String|    微信支付选填,支付宝不支持	     |   -	| 退款通知 url,支付宝会通知获取支付参数时的通知地址| 微信支付	  |
Q
qiang 已提交
406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437

**返回值说明**

|    参数名     |  类型  |     说明     | 支持平台 |
| :-----------: | :----: | :----------: | :------: |
|  outTradeNo   | String |  商户订单号  |     -     |
| transactionId | String |  平台订单号  |     -     |
|  outRefundNo  | String | 商户退款单号 | 微信支付 |
|   refundId    | String | 平台退款单号 |     -     |
|   refundFee   | Number |  退款总金额  |     -     |
| cashRefundFee | Number | 现金退款金额 |     -     |

**使用示例**

```js
exports.main = async function (event) {
  let res = await unipayIns.refund({
    outTradeNo: '商户订单号',
    outRefundNo: '商户退款单号', // 支付宝可不填此项
    totalFee: 1, // 订单总金额,支付宝可不填此项
    refundFee: 1, // 退款总金额
  })
  return res
}
```

### 查询退款

`unipayIns.refundQuery`,提交退款申请后,通过调用该接口查询退款状态。

**入参说明**

C
chenruilong 已提交
438 439 440 441 442 443 444
|    参数名     |  类型  |                    必填                     | 默认值 |                                        说明                                        | 支持平台 |
| :-----------: | :----: |:-----------------------------------------:| :----: | :--------------------------------------------------------------------------------: | :------: |
|  outTradeNo   | String | 微信支付V3必填,微信支付V2四选一,支付宝和 transactionId 二选一 |   -    |                                     商户订单号                                     |     -     |
| transactionId | String |       微信支付V2四选一,支付宝和 outTradeNo 二选一       |   -    |                                     平台订单号                                     |     -     |
|  outRefundNo  | String |              微信支付V2四选一,支付宝必填              |   -    |                                    商户退款单号                                    |     -     |
|   refundId    | String |                 微信支付V2四选一                 |   -    |                                    平台退款单号                                    | 微信支付 |
|    offset     | Number |                 微信支付V2选填                  |   -    | 偏移量,当部分退款次数超过 10 次时可使用,表示返回的查询结果从这个偏移量开始取记录 |      -    |
Q
qiang 已提交
445 446 447 448 449 450 451

**注意**

- `outRefundNo`为使用支付宝请求退款接口时,传入的商户退款单号。如果在退款请求时未传入,则该值为创建交易时的商户订单号即`outTradeNo`

**返回值说明**

C
chenruilong 已提交
452 453 454 455 456 457 458 459 460 461
|     参数名     |              类型               |          说明          | 支持平台  |
| :------------: | :-----------------------------: |:--------------------:|:-----:|
|   outTradeNo   |             String              |        商户订单号         |   -   |
| transactionId  |             String              |        平台订单号         |   -   |
|    totalFee    |             Number              |         订单金额         |   -   |
|    refundId    |             String              | 平台退款单号,仅支付宝、微信支付V3返回 |   -   |
|   refundFee    |             Number              |        退款总金额         |   -   |
|   refundDesc   |             String              |         退款理由         |   -   |
|   refundList   |     Array<refundItem>     |   分笔退款信息,仅微信支付V2返回   | 微信支付V2 |
| refundRoyaltys | Array<refundRoyaltysItem> |    退分账明细信息,仅支付宝返回    | 支付宝支付 |
Q
qiang 已提交
462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525

**refundItem 说明**

|       参数名        |          类型           |                                                                                                           说明                                                                                                           | 支持平台 |
| :-----------------: | :---------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------: |
|     outRefundNo     |         String          |                                                                                                       商户退款单号                                                                                                       |     -     |
|      refundId       |         String          |                                                                                                       平台退款单号                                                                                                       |     -     |
|    refundChannel    |         String          |                                           退款渠道,ORIGINAL—原路退款,BALANCE—退回到余额,OTHER_BALANCE—原账户异常退到其他余额账户,OTHER_BANKCARD—原银行卡异常退到其他银行卡                                           |          |
|      refundFee      |         Number          |                                                                                                       申请退款金额                                                                                                       |     -     |
| settlementRefundFee |         Number          |                                                                      退款金额,退款金额=申请退款金额-非充值代金券退款金额,退款金额<=申请退款金额                                                                      |          |
|    refundStatus     |         String          | 退款状态,SUCCESS—退款成功,REFUNDCLOSE—退款关闭,PROCESSING—退款处理中,CHANGE—退款异常,退款到银行发现用户的卡作废或者冻结了,导致原路退款银行卡失败,可前往商户平台(pay.weixin.qq.com)-交易中心,手动处理此笔退款。 |          |
|   couponRefundFee   |         Number          |                                                                                                     总代金券退款金额                                                                                                     |     -     |
|  couponRefundCount  |         Number          |                                                                                                    退款代金券使用数量                                                                                                    |     -     |
|    refundAccount    |         String          |                                                                                                       退款资金来源                                                                                                       |     -     |
|  refundRecvAccout   |         String          |                                                                                                       退款入账账户                                                                                                       |     -     |
|  refundSuccessTime  |         String          |                                                                                                       退款成功时间                                                                                                       |     -     |
|     couponList      | Array<couponItem> |                                                                                                       分笔退款信息                                                                                                       |     -     |

**couponItem 说明**

|     参数名      |  类型  |        说明        | 支持平台 |
| :-------------: | :----: | :----------------: | :------: |
|   couponType    | String |     代金券类型     |     -     |
| couponRefundId  | String |   退款代金券 ID    |     -     |
| couponRefundFee | String | 单个代金券退款金额 |      -    |

**refundRoyaltysItem 说明**

|   参数名    |  类型  |                                                                           说明                                                                            | 支持平台 |
| :---------: | :----: | :-------------------------------------------------------------------------------------------------------------------------------------------------------: | :------: |
| fundChannel | String |                                                                    交易使用的资金渠道                                                                     |     -     |
|  bankCode   | String |                                                                  银行卡支付时的银行代码                                                                   |     -     |
|   amount    | Number |                                                                该支付工具类型所使用的金额                                                                 |     -     |
| realAmount  | Number |                                                                     渠道实际付款金额                                                                      |     -     |
|  fundType   | String | 渠道所使用的资金类型,目前只在资金渠道(fund_channel)是银行卡渠道(BANKCARD)的情况下才返回该信息(DEBIT_CARD:借记卡,CREDIT_CARD:信用卡,MIXED_CARD:借贷合一卡) |     -     |

**使用示例**

```js
exports.main = async function (event) {
  let res = await unipayIns.refundQuery({
    outTradeNo: '商户订单号',
    outRefundNo: '商户退款单号', // 支付宝必填
  })
  return res
}
```

### 下载交易账单

`unipayIns.downloadBill`,商户可以通过该接口下载历史交易清单。**仅微信支付支持**

**注意:**

1. 微信侧未成功下单的交易不会出现在对账单中。支付成功后撤销的交易会出现在对账单中,跟原支付单订单号一致;
2. 微信在次日 9 点启动生成前一天的对账单,建议商户 10 点后再获取;
3. 对账单中涉及金额的字段单位为“元”。
4. 对账单接口只能下载三个月以内的账单。
5. 对账单是以商户号纬度来生成的,如一个商户号与多个 appid 有绑定关系,则使用其中任何一个 appid 都可以请求下载对账单。对账单中的 appid 取自交易时候提交的 appid,与请求下载对账单时使用的 appid 无关。

**入参说明**

|  参数名  |  类型  | 必填 | 默认值 |                                                                                              说明                                                                                              | 支持平台 |
| :------: | :----: | :--: | :----: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------: |
C
chenruilong 已提交
526
| billDate | String | 必填 |   -    |                                                                                下载对账单的日期,格式:2014-06-03                                                                                |     -     |
Q
qiang 已提交
527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586
| billType | String | 选填 |  ALL   | ALL(默认值),返回当日所有订单信息(不含充值退款订单),SUCCESS,返回当日成功支付的订单(不含充值退款订单),REFUND,返回当日退款订单(不含充值退款订单),RECHARGE_REFUND,返回当日充值退款订单 |     -     |

**返回值说明**

| 参数名  |  类型  |           说明           | 支持平台 |
| :-----: | :----: | :----------------------: | :------: |
| content | String | 文本表格的方式返回的数据 |     -     |

`content`示例如下

**当日所有订单**
交易时间,公众账号 ID,商户号,子商户号,设备号,微信订单号,商户订单号,用户标识,交易类型,交易状态,付款银行,货币种类,总金额,代金券或立减优惠金额,微信退款单号,商户退款单号,退款金额, 代金券或立减优惠退款金额,退款类型,退款状态,商品名称,商户数据包,手续费,费率

**当日成功支付的订单**
交易时间,公众账号 ID,商户号,子商户号,设备号,微信订单号,商户订单号,用户标识,交易类型,交易状态,付款银行,货币种类,总金额, 代金券或立减优惠金额,商品名称,商户数据包,手续费,费率

**当日退款的订单**
交易时间,公众账号 ID,商户号,子商户号,设备号,微信订单号,商户订单号,用户标识,交易类型,交易状态,付款银行,货币种类,总金额, 代金券或立减优惠金额,退款申请时间,退款成功时间,微信退款单号,商户退款单号,退款金额, 代金券或立减优惠退款金额,退款类型,退款状态,商品名称,商户数据包,手续费,费率

从第二行起,为数据记录,各参数以逗号分隔,参数前增加`符号,为标准键盘 1 左边键的字符,字段顺序与表头一致。

倒数第二行为订单统计标题,最后一行为统计数据

总交易单数,总交易额,总退款金额,总代金券或立减优惠退款金额,手续费总金额

举例如下:

```
交易时间,公众账号ID,商户号,子商户号,设备号,微信订单号,商户订单号,用户标识,交易类型,交易状态,付款银行,货币种类,总金额,代金券或立减优惠金额,微信退款单号,商户退款单号,退款金额,代金券或立减优惠退款金额,退款类型,退款状态,商品名称,商户数据包,手续费,费率
`2014-11-10 16:33:45,`wx2421b1c4370ec43b,`10000100,`0,`1000,`1001690740201411100005734289,`1415640626,`085e9858e3ba5186aafcbaed1,`MICROPAY,`SUCCESS,`OTHERS,`CNY,`0.01,`0.0,`0,`0,`0,`0,`,`,`被扫支付测试,`订单额外描述,`0,`0.60%
`2014-11-10 16:46:14,`wx2421b1c4370ec43b,`10000100,`0,`1000,`1002780740201411100005729794,`1415635270,`085e9858e90ca40c0b5aee463,`MICROPAY,`SUCCESS,`OTHERS,`CNY,`0.01,`0.0,`0,`0,`0,`0,`,`,`被扫支付测试,`订单额外描述,`0,`0.60%
总交易单数,总交易额,总退款金额,总代金券或立减优惠退款金额,手续费总金额
`2,`0.02,`0.0,`0.0,`0
```

**使用示例**

```js
exports.main = async function (event) {
  let res = await unipayIns.downloadBill({
    billDate: '20200202',
  })
  return res
}
```

### 下载资金账单

`unipayIns.downloadFundflow`,商户可以通过该接口下载自 2017 年 6 月 1 日起的历史资金流水账单。**仅微信支持**

**说明:**

1. 资金账单中的数据反映的是商户微信账户资金变动情况;
2. 当日账单在次日上午 9 点开始生成,建议商户在上午 10 点以后获取;
3. 资金账单中涉及金额的字段单位为“元”。

**入参说明**

|   参数名    |  类型  | 必填 | 默认值 |                                  说明                                   | 支持平台 |
| :---------: | :----: | :--: | :----: | :---------------------------------------------------------------------: | :------: |
C
chenruilong 已提交
587
|  billDate   | String | 必填 |   -    |                    下载对账单的日期,格式:2014-06-03                     |    -     |
Q
qiang 已提交
588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662
| accountType | String | 选填 | Basic  | 账单的资金来源账户:Basic 基本账户,Operation 运营账户,Fees 手续费账户 |     -     |

**返回值说明**

| 参数名  |  类型  |           说明           | 支持平台 |
| :-----: | :----: | :----------------------: | :------: |
| content | String | 文本表格的方式返回的数据 |     -    |

`content`示例如下

- 第一行为表头

记账时间,微信支付业务单号,资金流水单号,业务名称,业务类型,收支类型,收支金额(元),账户结余(元),资金变更提交申请人,备注,业务凭证号

- 从第二行起,为资金流水数据,各参数以逗号分隔,参数前增加`符号,为标准键盘 1 左边键的字符,字段顺序与表头一致

- 倒数第二行为资金账单统计标题

资金流水总笔数,收入笔数,收入金额,支出笔数,支出金额

- 最后一行为统计数据

账单示例如下:

```
记账时间,微信支付业务单号,资金流水单号,业务名称,业务类型,收支类型,收支金额(元),账户结余(元),资金变更提交申请人,备注,业务凭证号

`2018-02-01 04:21:23,`50000305742018020103387128253,`1900009231201802015884652186,`退款,`退款,`支出,`0.02,`0.17,`system,`缺货,`REF4200000068201801293084726067

资金流水总笔数,收入笔数,收入金额,支出笔数,支出金额

`20.0,`17.0,`0.35,`3.0,`0.18
```

**使用示例**

```js
exports.main = async function (event) {
  let res = await unipayIns.downloadFundflow({
    billDate: '20200202',
  })
  return res
}
```

### 支付结果通知处理

**注意:支付宝在非全量退款时也会发送通知到支付时设置的notify_url**

`unipayIns.verifyPaymentNotify`,用于在使用云函数 Url 化的云函数内检验并处理支付结果。

**入参说明**

只接收对应云函数的`event`作为参数

**返回值说明**

|    参数名     |  类型  |                        说明                         | 支持平台 |
| :-----------: | :----: | :-------------------------------------------------: | :------: |
|   totalFee    | Number |                     订单总金额                      |     -     |
|    cashFee    | Number |                    现金支付金额                     |      -    |
|    feeType    | String |                      货币类别                       |     -     |
|  outTradeNo   | String |                     商户订单号                      |     -     |
| transactionId | String |                     平台订单号                      |     -     |
|    timeEnd    | String |         支付完成时间,格式为 yyyyMMddHHmmss         |      -    |
|    openid     | String |                       用户 id                       |     -     |
|  returnCode   | String | 值 SUCCESS 时为支付成功,通常需要校验订单金额等参数 |      -    |

**使用示例**

```js
exports.main = async function (event) {
  let res = await unipayIns.verifyPaymentNotify(event)
  // 处理完毕其他业务
  // 注意如果处理成功需要严格按照下面的格式进行返回,否则厂商会持续通知
C
chenruilong 已提交
663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682
  // 微信支付V3处理成功之后 
  return {
    mpserverlessComposedResponse: true,
    statusCode: 200,
    headers: {
      'content-type': 'application/json'
    },
    body: JSON.stringify({
        code: 'SUCCESS',
        message: '成功'
    })
  }
  // 微信支付V2处理成功之后 
  return {
    mpserverlessComposedResponse: true, 
    statusCode: 200,
    headers: {
      'content-type': 'text/xml;charset=utf-8'
    },
    body: `<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>`
Q
qiang 已提交
683 684
  }
  // 支付宝处理成功后  
C
chenruilong 已提交
685 686
  return {
    mpserverlessComposedResponse: true,
Q
qiang 已提交
687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730
    statusCode: 200,
    headers: {  
      'content-type': 'text/plain'  
    },  
    body: "success"
  }
}
```

### 退款结果通知@verify-refund-notify

**注意:支付宝在非全量退款时才会发送通知,通知地址为支付时设置的notify_url**

> uni-pay 1.0.17版本起新增对支付宝退款结果通知的支持

`unipayIns.verifyRefundNotify`,用于在使用云函数 Url 化的云函数内检验并处理支付结果。

**入参说明**

只接收对应云函数的`event`作为参数

**返回值说明**

|       参数名				|  类型	|                         说明													| 支持平台|
| :-----------------:	| :----:| :---------------------------------------------------:	| :------:|
|      totalFee				| Number|                      订单总金额												|    -		|
|      refundFee			| Number|                     申请退款金额											|    -		|
| settlementTotalFee	| Number|                     应结订单金额,支付宝不返回				|    -		|
| settlementRefundFee	| Number|                       退款金额,支付宝不返回					|   -			|
|     outTradeNo			| String|                      商户订单号												|    -		|
|    transactionId		| String|                      平台订单号												|    -		|
|      refundId				| String|                     平台退款单号,支付宝不返回				|    -		|
|     outRefundNo			| String|                     商户退款单号											|    -		|
|    refundStatus			| String| SUCCESS-退款成功,CHANGE-退款异常,REFUNDCLOSE—退款关闭|      -	|
|    refundAccount		| String|                     退款资金来源,支付宝不返回				|    -		|
|  refundRecvAccout		| String|                     退款入账账户,支付宝不返回				|    -		|

**使用示例**

```js
exports.main = async function (event) {
  let res = await unipayIns.verifyRefundNotify(event)
  // 注意如果处理成功需要严格按照下面的格式进行返回,否则厂商会持续通知
  // 微信处理成功之后 
C
chenruilong 已提交
731 732
  return {
    mpserverlessComposedResponse: true,
Q
qiang 已提交
733 734 735 736 737 738 739
    statusCode: 200,  
    headers: {  
        'content-type': 'text/xml;charset=utf-8'  
    },  
    body: `<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>`  
  }
  // 支付宝处理成功后  
C
chenruilong 已提交
740 741
  return {
    mpserverlessComposedResponse: true,
Q
qiang 已提交
742
    statusCode: 200,
C
chenruilong 已提交
743
    headers: {
Q
qiang 已提交
744
      'content-type': 'text/plain'  
C
chenruilong 已提交
745
    },
Q
qiang 已提交
746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778
    body: "success"
  }
}
```

### 获取通知类型@check-notify-type

> 新增于 uni-id 1.0.17

`unipayIns.checkNotifyType`,用于在使用云函数 Url 化的云函数内检验当前通知的类型。由于支付宝支付在非全量退款时会调用支付时设置的notify_url,可以使用此接口在调用校验通知之前判断通知类型

**入参说明**

只接收对应云函数的`event`作为参数

**返回值说明**

此接口会返回一个字符串,可能的值如下

- `refund`:当前是一个退款通知
- `payment`:当前是一个支付结果通知

**使用示例**

```js
exports.main = async function (event) {
  let res = await unipayIns.checkNotifyType(event)
  if(res === 'refund') {
    // 退款通知
  } else if(res === 'payment') {
    // 支付结果通知
  }
}
J
jrptest 已提交
779 780 781
```


782
### 苹果内购-校验支付凭证@verifyReceipt
J
jrptest 已提交
783 784 785 786 787 788 789

`unipayIns.verifyReceipt`, 校验iap支付凭证返回交易信息。

**入参说明**

|    参数名     |  类型  |          必填           | 默认值 |    说明    | 支持平台 |
| :-----------: | :----: | :---------------------: | :----: | :--------: | :------: |
790
| receiptData   | String |       是                |   -    | 支付凭证 |    苹果内购支付     |
J
jrptest 已提交
791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811

**返回值说明**

|       参数名       |  类型  |                                                                                                                                                                          说明                                                                                                                                                                          | 支持平台 |
| :----------------: | :----: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------: |
|   transactionId    | String |                                                                                                                                                                       交易标示                                                                                                                                                                       |      -    |
|     tradeState     | String | 订单状态 ,微信支付: SUCCESS—支付成功,REFUND—转入退款,NOTPAY—未支付,PAYERROR--支付失败(其他原因,如银行返回失败),SUCCESS(交易支付成功)。 |     -     |
|      totalFee      | Number |                                                                                                                                                                  标价金额 ,单位:分                                                                                                                                                                   |     -     |
| settlementTotalFee | Number |                                                                                                                                                                 应结订单金额,单位:分                                                                                                                                                                 |     -     |
|      receipt       | Object |                                                                                                                                                                 收据信息                                                                                                                                                                               |  -  |

**使用示例**

```js
exports.main = async function (event) {
  let res = await unipayIns.verifyReceipt({
    receiptData: 'transactionReceipt',
  })
  return res
}
```