# WAP跳转支付

对于具有一定开发能力的商户，可以通过对接Upay支付网关来支持WAP支付，让顾客可以直接在商户的网页上进行移动支付。

**注意**：
- 请求方式为GET，需使用302跳转方式访问
- 商户务必以查单或者服务器异步通知的订单结果为主作出正确的处理。return_url的结果仅供参考。
- 查询订单请使用查询接口（/upay/v2/query）轮询，轮询时间控制在100-120s之间，轮询间隔建议前30秒内2秒一次，之后5秒一次

## 接口说明

- 请求方式：`GET`
- 请求地址：`https://qr.shouqianba.com/gateway`
- Operation ID：`wapPay`

## 请求参数

| 参数名 | 位置 | 类型 | 必填 | 描述 |
| --- | --- | --- | --- | --- |
| terminal_sn | query | string | 是 | 收钱吧终端ID |
| client_sn | query | string | 是 | 商户系统订单号。必须在商户系统内唯一；且长度不超过32字节 |
| total_amount | query | string | 是 | 交易总金额。以分为单位，不超过10位纯数字字符串 |
| subject | query | string | 是 | 交易概述 |
| payway | query | string | 否 | 支付方式。不传默认选择当前环境支持的支付方式。1:支付宝 3:微信 18:翼支付 |
| operator | query | string | 是 | 门店操作员 |
| description | query | string | 否 | 商品详情 |
| longitude | query | string | 否 | 经度。经纬度必须同时出现 |
| latitude | query | string | 否 | 纬度。经纬度必须同时出现 |
| extended | query | string | 否 | 扩展参数集合的JSON字符串。收钱吧与特定第三方单独约定的参数集合，最多支持24个字段，每个字段key长度不超过64字节，value长度不超过256字节 |
| goods_details | query | string | 否 | 商品详情的JSON数组字符串 |
| reflect | query | string | 否 | 反射参数。任何调用者希望原样返回的信息 |
| notify_url | query | string | 否 | 支付回调的地址。如果支付成功通知时间间隔为1s,5s,30s,600s |
| return_url | query | string | 是 | 页面跳转同步通知页面路径。处理完请求后，当前页面自动跳转到商户网站里指定页面的http路径 |
| sign | query | string | 是 | 签名。规则：1.剔除sign参数；2.按ASCII码递增排序其余参数；3.拼接为'参数=参数值&key=terminal_key'；4.MD5后转大写 |

## 请求体

无请求体定义。

## 响应体

| 字段名 | 类型 | 必填 | 描述 |
| --- | --- | --- | --- |
| client_sn | string | 是 | 商户系统订单号 |
| error_code | string | 否 | 错误码。仅 is_success 为 F 时出现 |
| error_message | string | 否 | 错误描述。仅 is_success 为 F 时出现 |
| is_success | string | 是 | 成功标识。T/F，表示接口调用是否成功，并不表明业务处理结果 |
| operator | string | 是 | 门店操作员 |
| reflect | string | 否 | 反射参数 |
| result_code | string | 否 | 业务错误码（deprecated）。仅status为FAIL且是微信支付时存在 |
| result_message | string | 否 | 业务错误描述（deprecated）。仅status为FAIL且是微信支付时存在 |
| sign | string | 是 | 签名 |
| sn | string | 是 | 收钱吧唯一订单号 |
| status | string | 否 | 支付状态。SUCCESS：成功；FAIL：失败 |
| subject | string | 是 | 交易概述 |
| terminal_sn | string | 是 | 收钱吧终端ID |
| total_amount | string | 是 | 交易总金额 |
| trade_no | string | 是 | 支付服务商订单号 |

## 响应示例

```json
{
  "client_sn": "string_value",
  "error_code": "string_value",
  "error_message": "string_value",
  "is_success": "string_value",
  "operator": "string_value",
  "reflect": "string_value",
  "result_code": "string_value",
  "result_message": "string_value",
  "sign": "string_value",
  "sn": "string_value",
  "status": "string_value",
  "subject": "string_value",
  "terminal_sn": "string_value",
  "total_amount": "string_value",
  "trade_no": "string_value"
}
```

## 示例代码

### cURL

```bash
curl -G -X GET "https://qr.shouqianba.com/gateway" \
  --data-urlencode "terminal_sn=terminal_sn_value" \
  --data-urlencode "client_sn=client_sn_value" \
  --data-urlencode "total_amount=total_amount_value" \
  --data-urlencode "subject=subject_value" \
  --data-urlencode "payway=payway_value" \
  --data-urlencode "operator=operator_value" \
  --data-urlencode "description=description_value" \
  --data-urlencode "longitude=longitude_value" \
  --data-urlencode "latitude=latitude_value" \
  --data-urlencode "extended=extended_value" \
  --data-urlencode "goods_details=goods_details_value" \
  --data-urlencode "reflect=reflect_value" \
  --data-urlencode "notify_url=notify_url_value" \
  --data-urlencode "return_url=return_url_value" \
  --data-urlencode "sign=sign_value" \
  -H "Authorization: 100000000000000000 0123456789abcdef0123456789abcdef"
```

### Python

```python
import requests

url = "https://qr.shouqianba.com/gateway"
headers = {"Content-Type": "application/json",
    "Authorization": "100000000000000000 0123456789abcdef0123456789abcdef",
}
params = {
    "terminal_sn": "terminal_sn_value",
    "client_sn": "client_sn_value",
    "total_amount": "total_amount_value",
    "subject": "subject_value",
    "payway": "payway_value",
    "operator": "operator_value",
    "description": "description_value",
    "longitude": "longitude_value",
    "latitude": "latitude_value",
    "extended": "extended_value",
    "goods_details": "goods_details_value",
    "reflect": "reflect_value",
    "notify_url": "notify_url_value",
    "return_url": "return_url_value",
    "sign": "sign_value",
}

response = requests.get(
    url,
    headers=headers,
    params=params,
)

try:
    print(response.json())
except ValueError:
    print(response.text)
```

### Java

```java
// WAP跳转支付
OkHttpClient client = new OkHttpClient();
HttpUrl url = HttpUrl.parse("https://qr.shouqianba.com/gateway").newBuilder()
    .addQueryParameter("terminal_sn", "terminal_sn_value")
    .addQueryParameter("client_sn", "client_sn_value")
    .addQueryParameter("total_amount", "total_amount_value")
    .addQueryParameter("subject", "subject_value")
    .addQueryParameter("payway", "payway_value")
    .addQueryParameter("operator", "operator_value")
    .addQueryParameter("description", "description_value")
    .addQueryParameter("longitude", "longitude_value")
    .addQueryParameter("latitude", "latitude_value")
    .addQueryParameter("extended", "extended_value")
    .addQueryParameter("goods_details", "goods_details_value")
    .addQueryParameter("reflect", "reflect_value")
    .addQueryParameter("notify_url", "notify_url_value")
    .addQueryParameter("return_url", "return_url_value")
    .addQueryParameter("sign", "sign_value")
    .build();
Request request = new Request.Builder()
    .url(url)
    .addHeader("Authorization", "100000000000000000 0123456789abcdef0123456789abcdef")
    .get()
    .build();
Response response = client.newCall(request).execute();
System.out.println(response.body().string());
```

### Go

```go
package main

import (
    "fmt"
    "io"
    "net/http"
)

func main() {
	req, err := http.NewRequest("GET", "https://qr.shouqianba.com/gateway", nil)
	if err != nil {
		panic(err)
	}
	q := req.URL.Query()
	q.Set("terminal_sn", "terminal_sn_value")
	q.Set("client_sn", "client_sn_value")
	q.Set("total_amount", "total_amount_value")
	q.Set("subject", "subject_value")
	q.Set("payway", "payway_value")
	q.Set("operator", "operator_value")
	q.Set("description", "description_value")
	q.Set("longitude", "longitude_value")
	q.Set("latitude", "latitude_value")
	q.Set("extended", "extended_value")
	q.Set("goods_details", "goods_details_value")
	q.Set("reflect", "reflect_value")
	q.Set("notify_url", "notify_url_value")
	q.Set("return_url", "return_url_value")
	q.Set("sign", "sign_value")
	req.URL.RawQuery = q.Encode()
	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("Authorization", "100000000000000000 0123456789abcdef0123456789abcdef")
	resp, err := (&http.Client{}).Do(req)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()
	respBytes, err := io.ReadAll(resp.Body)
	if err != nil {
		panic(err)
	}
	fmt.Println(string(respBytes))
}
```

### Node.js

```javascript
const https = require("https");

const options = {
  method: "GET",
  hostname: "qr.shouqianba.com",
  path: "/gateway?terminal_sn=terminal_sn_value&client_sn=client_sn_value&total_amount=total_amount_value&subject=subject_value&payway=payway_value&operator=operator_value&description=description_value&longitude=longitude_value&latitude=latitude_value&extended=extended_value&goods_details=goods_details_value&reflect=reflect_value&notify_url=notify_url_value&return_url=return_url_value&sign=sign_value",
  headers: {
    "Authorization": "100000000000000000 0123456789abcdef0123456789abcdef",
    "Content-Type": "application/json"
  }
};

const req = https.request(options, (res) => {
  let data = "";
  res.on("data", (chunk) => { data += chunk; });
  res.on("end", () => { try { console.log(JSON.parse(data)); } catch (_) { console.log(data); } });
});
req.end();
```
