﻿## 接口说明

接口名称：`alipay.aipay.nowpay.purchase.create`

获取普通购买入口或锁定指定档位的购买入口。传入 `sku_id` 时锁定该档位；不传时由用户在托管购买页选择可售档位。

## 适用场景

- 额度不足时引导用户购买次数包或积分包。
- 用户主动加购额度，即使当前仍有余额。
- 平台已展示档位并希望直接打开指定档位购买页。

## 注意事项

- `out_request_no` 标识一次获取购买入口的请求，不是支付宝交易号。平台应为每次独立请求生成唯一值并持久化；超时重试使用原值与原参数。
- 幂等复用有有效期，不是永久订单查询能力。链接失效时间以 `expire_time` 为准；仅在确认旧入口失效并需要新购买入口时创建新请求，不能因超时立即换号。
- `sku_id` 必须取自当前商品 `charge.query` 的可售档位。不传 `sku_id` 时打开可选档位的普通购买页，响应可不包含 `charging_option`。
- `callback_url` 如传入，使用 `HTTPS` 地址。支付页面返回后，买断或时长包调用 `purchase.consult`；额度包调用 `quota.query`。
- 额度包支持有余额时加购。买断或时长包已有可用权益，或权益处于不可重购状态时，可能拒绝生成新的购买入口。获取链接成功不等于支付成功。

## 公共请求参数

| 参数 | 类型 | 是否必选 | 最大长度 | 描述 | 示例值 |
| --- | --- | --- | --- | --- | --- |
| `app_id` | String | 必选 | 32 | 支付宝分配给开发者的应用ID | `YOUR_APP_ID` |
| `method` | String | 必选 | 128 | 接口名称 | `alipay.aipay.nowpay.purchase.create` |
| `format` | String | 可选 | 40 | 仅支持JSON | `JSON` |
| `charset` | String | 必选 | 10 | 请求使用的编码格式，如utf-8,gbk,gb2312等 | `utf-8` |
| `sign_type` | String | 必选 | 10 | 请求签名算法，推荐 RSA2 | `RSA2` |
| `sign` | String | 必选 | 344 | 商户请求参数的签名串，详见[签名](https://opendocs.alipay.com/common/02khjm) | `详见示例` |
| `timestamp` | String | 必选 | 19 | 发送请求的时间，格式"yyyy-MM-dd HH:mm:ss" | `2026-09-07 10:00:00` |
| `version` | String | 必选 | 3 | 调用的接口版本，固定为：1.0 | `1.0` |
| `app_auth_token` | String | 可选 | 40 | 已获授权的第三方代调用场景使用的应用授权令牌，详见[应用授权概述](https://opendocs.alipay.com/isv/10467/xldcyq) | - |
| `biz_content` | String | 必选 | - | 业务请求参数的 JSON 字符串，字段使用 snake_case；详见下表 | - |

## 业务请求参数

业务字段统一放入 `biz_content`。下表数组子字段使用 `[]` 表示元素路径。

| 参数 | 类型 | 是否必选 | 最大长度 | 描述 | 注意事项/枚举值 | 示例值 |
| --- | --- | --- | --- | --- | --- | --- |
| `out_request_no` | String | 必选 | 128 | 平台生成的幂等请求号 | 重试保持原值与原业务参数；不同请求使用不同值 | `purchase_20260907_000001` |
| `out_product_id` | String | 必选 | 128 | 平台内稳定的商品或应用标识 | - | `app_writing_001` |
| `external_owner_id` | String | 必选 | 128 | 平台内稳定的创作者或商品所有者标识 | 与配置时使用的标识一致；不是必须填写支付宝账号 | `creator_001` |
| `external_buyer_id` | String | 必选 | 128 | 平台内稳定的权益受益人标识 | 与平台登录用户绑定；不等同于付款账号 | `user_001` |
| `sku_id` | String | 可选 | 128 | 档位标识 | 取自当前商品的 `charging_options`；不传则在购买页选择档位 | `S0806000200863003` |
| `callback_url` | String | 可选 | 512 | 购买完成返回地址 | 页面返回地址，不是异步通知地址；返回后重新查询状态；如传入必须为 `HTTPS` | `https://platform.example.com/nowpay/purchase-return` |

## 常见请求示例

示例商品、用户、域名及请求号均为演示值。Java 使用包含该接口请求类的支付宝服务端 SDK；示例按公钥模式初始化，私钥仅保存在平台服务端。cURL 中的签名需在发送前按全部实际参数生成；如增加 `app_auth_token`，应一起参与签名。

::::aipay-tabs{defaultActiveKey="Java"}

:::aipay-tab{key="Java" title="Java"}
```java
import com.alipay.api.AlipayConfig;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayAipayNowpayPurchaseCreateRequest;
import com.alipay.api.response.AlipayAipayNowpayPurchaseCreateResponse;

public class NowpayExample {
    public static void main(String[] args) throws Exception {
        AlipayConfig config = new AlipayConfig();
        config.setServerUrl("https://openapi.alipay.com/gateway.do");
        config.setAppId(System.getenv("ALIPAY_APP_ID"));
        config.setPrivateKey(System.getenv("ALIPAY_PRIVATE_KEY"));
        config.setAlipayPublicKey(System.getenv("ALIPAY_PUBLIC_KEY"));
        config.setFormat("json");
        config.setCharset("UTF-8");
        config.setSignType("RSA2");
        AlipayClient client = new DefaultAlipayClient(config);

        AlipayAipayNowpayPurchaseCreateRequest request = new AlipayAipayNowpayPurchaseCreateRequest();
        request.setBizContent("{\"out_request_no\":\"purchase_20260907_000001\",\"out_product_id\":\"app_writing_001\",\"external_owner_id\":\"creator_001\",\"external_buyer_id\":\"user_001\",\"sku_id\":\"S0806000200863003\",\"callback_url\":\"https://platform.example.com/nowpay/purchase-return\"}");
        // 仅在已获授权的第三方代调用场景设置 app_auth_token。
        String appAuthToken = System.getenv("ALIPAY_APP_AUTH_TOKEN");
        if (appAuthToken != null && !appAuthToken.isEmpty()) {
            request.putOtherTextParam("app_auth_token", appAuthToken);
        }
        AlipayAipayNowpayPurchaseCreateResponse response = client.execute(request);
        if (!response.isSuccess()) {
            // 按 code/sub_code 处理；结果未知时保留原业务请求号。
            System.out.println(response.getCode() + ":" + response.getSubCode());
            return;
        }
        // 网关成功后，按本页“结果处理”读取业务字段。
        System.out.println(response.getBody());
    }
}
```
:::

:::aipay-tab{key="cURL" title="cURL"}
```bash
biz_content='{
  "out_request_no": "purchase_20260907_000001",
  "out_product_id": "app_writing_001",
  "external_owner_id": "creator_001",
  "external_buyer_id": "user_001",
  "sku_id": "S0806000200863003",
  "callback_url": "https://platform.example.com/nowpay/purchase-return"
}'

# app_id、timestamp、sign 由平台准备；sign 必须基于本次完整参数生成。
curl --request POST 'https://openapi.alipay.com/gateway.do' \
  --data-urlencode "app_id=${app_id}" \
  --data-urlencode 'method=alipay.aipay.nowpay.purchase.create' \
  --data-urlencode 'format=json' \
  --data-urlencode 'charset=UTF-8' \
  --data-urlencode 'sign_type=RSA2' \
  --data-urlencode "timestamp=${timestamp}" \
  --data-urlencode 'version=1.0' \
  --data-urlencode "biz_content=${biz_content}" \
  --data-urlencode "sign=${sign}"
```
:::

::::

## 公共响应参数

| 参数 | 类型 | 是否必选 | 最大长度 | 描述 | 示例值 |
| --- | --- | --- | --- | --- | --- |
| `code` | String | 必选 | - | 网关返回码；10000 表示接口调用成功 | `10000` |
| `msg` | String | 必选 | - | 网关返回码说明 | `Success` |
| `sub_code` | String | 可选 | - | 业务错误码；仅用于接口失败处理 | - |
| `sub_msg` | String | 可选 | - | 业务错误说明；不用于编写固定业务分支 | - |
| `sign` | String | 必选 | - | 响应签名，位于响应根对象；由 SDK 按配置验签 | - |

响应业务对象名为 `alipay_aipay_nowpay_purchase_create_response`。先完成验签并判断 `code`，再读取业务结果。

## 业务响应参数

> 协议核对：当前开放平台预览将 `charging_option` 定义为数组；本稿依据现有实现整理为单对象，且普通入口可不返回。编写解析代码前需确认最终网关结构。

| 参数 | 类型 | 是否必选 | 最大长度 | 描述 | 注意事项/枚举值 | 示例值 |
| --- | --- | --- | --- | --- | --- | --- |
| `purchase_url` | String | 必选 | 512 | 托管购买页 | - | `alipays://platformapi/startapp?appId=2021006180624128&page=pages%2Forder%2Findex%3FpurchaseLinkId%3DSAMPLE_LINK_ID` |
| `purchase_qr_code` | String | 可选 | 512 | 购买二维码 | - | `https://mobilecodec.alipay.com/show.htm?code=SAMPLE_QR_CODE` |
| `expire_time` | String | 必选 | 32 | 链接失效时间；格式 `yyyy-MM-dd HH:mm:ss`，时区 `Asia/Shanghai` | - | `2026-09-07 10:30:00` |
| `charging_option` | Object | 特殊可选 | - | 选中档位摘要 | 指定 `sku_id` 且成功生成指定档位链接时返回；普通链接可不返回 | - |
| `charging_option.sku_id` | String | 必选 | 32 | 档位标识，平台原样回传 | 按不透明标识保存和回传，不解析内容 | `S0806000200863003` |
| `charging_option.plan_id` | String | 必选 | 32 | 价格计划标识 | 按不透明标识保存和回传，不解析内容 | `PI0806000200864210` |
| `charging_option.display_name` | String | 必选 | 32 | 档位名称 | - | `20次包` |
| `charging_option.billing_mode` | String | 必选 | 32 | 档位类型 | 永久买断:`ONE_TIME`；时长包:`ONE_TIME_DURATION`；额度包:`QUANTITY` | `QUANTITY` |
| `charging_option.price` | String | 必选 | 32 | 展示价格，十进制，单位元 | - | `1.00` |
| `charging_option.currency` | String | 必选 | 32 | 货币 | - | `CNY` |
| `charging_option.price_version` | Number | 必选 | 32 | 价格快照版本 | 整数；价格快照版本，仅展示和记录，不作为购买请求参数 | `1` |
| `charging_option.entitlement_rule` | String | 必选 | 32 | 权益类型 | `PERPETUAL`：买断；`FIXED_DURATION`：时长包；`QUOTA`：额度包 | `QUOTA` |
| `charging_option.duration_period` | String | 特殊可选 | 32 | 时长包周期类型 | `billing_mode`=`ONE_TIME_DURATION` 时返回；`WEEK` / `MONTH` / `QUARTER` / `YEAR` | `WEEK` |
| `charging_option.quota_unit` | String | 特殊可选 | 32 | 额度类型 | `billing_mode`=`QUANTITY` 时使用；`COUNT`：次数，`POINT`：积分 | `COUNT` |
| `charging_option.quota_amount` | Number | 特殊可选 | 32 | 次数或积分数量，单位个 | `billing_mode`=`QUANTITY` 时返回；购买该档位增加的整数额度 | `20` |

## 结果处理

成功后打开 `purchase_url` 或展示 `purchase_qr_code`。链接、二维码和令牌都使用接口实际返回值，不解析、不拼接。到期后先刷新用户权益或额度，再按用户购买意图获取新入口。

## 响应示例

以下为按单一业务场景整理的示例。签名、链接令牌和二维码均为占位值，不可直接使用。

::::aipay-tabs{defaultActiveKey="正常示例"}

:::aipay-tab{key="正常示例" title="正常示例"}
```json
{
  "alipay_aipay_nowpay_purchase_create_response": {
    "code": "10000",
    "msg": "Success",
    "purchase_url": "alipays://platformapi/startapp?appId=2021006180624128&page=pages%2Forder%2Findex%3FpurchaseLinkId%3DSAMPLE_LINK_ID",
    "purchase_qr_code": "https://mobilecodec.alipay.com/show.htm?code=SAMPLE_QR_CODE",
    "expire_time": "2026-09-07 10:30:00",
    "charging_option": {
      "sku_id": "S0806000200863003",
      "plan_id": "PI0806000200864210",
      "display_name": "20次包",
      "billing_mode": "QUANTITY",
      "price": "1.00",
      "currency": "CNY",
      "price_version": 1,
      "entitlement_rule": "QUOTA",
      "quota_unit": "COUNT",
      "quota_amount": 20
    }
  },
  "sign": "RESPONSE_SIGNATURE_PLACEHOLDER"
}
```
:::

:::aipay-tab{key="异常示例" title="异常示例"}
```json
{
  "alipay_aipay_nowpay_purchase_create_response": {
    "code": "20000",
    "msg": "Service Currently Unavailable",
    "sub_code": "isp.unknow-error",
    "sub_msg": "系统繁忙"
  },
  "sign": "ERITJKEIJKJHKKKKKKKHJEREEEEEEEEEEE"
}
```
:::

::::

### 普通购买入口

不传 `sku_id` 时，由用户在托管页选择档位，响应可省略 `charging_option`。

```json
{
  "alipay_aipay_nowpay_purchase_create_response": {
    "code": "10000",
    "msg": "Success",
    "purchase_url": "alipays://platformapi/startapp?appId=2021006180624128&page=pages%2Forder%2Findex%3FpurchaseLinkId%3DSAMPLE_LINK_ID",
    "purchase_qr_code": "https://mobilecodec.alipay.com/show.htm?code=SAMPLE_QR_CODE",
    "expire_time": "2026-09-07 10:30:00"
  },
  "sign": "RESPONSE_SIGNATURE_PLACEHOLDER"
}
```

## 公共错误码

参见[支付宝公共错误码](https://opendoc.alipay.com/common/02km9f)。网关或系统异常时，按原请求查询或重试；写操作不能在结果未确认时更换幂等号。

## 业务错误码

以下保留当前开放平台预览已列出的错误码，并补充平台处理建议。错误码列表可能扩展，平台应保留未知错误的待确认处理。

| 错误码 | 错误描述 | 解决方案 |
| --- | --- | --- |
| `SYSTEM_ERROR` | 系统繁忙 | 稍后使用原参数重试；消费结果未知时先查询原请求 |
| `INVALID_PARAMETER` | 参数有误 | 请根据接口返回的参数非法的具体错误信息，修改参数后进行重试 |
| `BILLING_MODE_NOT_SUPPORTED` | 计价模式不支持 | 请确认商品收费模式 |
| `NOW_PAY_BINDING_INVALID` | 商品绑定关系不存在/不匹配 | 请先完成商品配置上架 |
| `NOW_PAY_CHARGING_OPTION_UNAVAILABLE` | 指定档位已下架或不存在 | 确认 `sku_id`与 `charge.query` 返回的可售档位一致 |
| `NOW_PAY_ORDER_CONFLICT` | 同一幂等请求号对应的业务参数不一致 | 核对原请求参数；原请求结果未知时不要换号重试 |
| `NOW_PAY_PRODUCT_NOT_PURCHASABLE` | 用户已有不可重购权益 | 用户已有不可重购权益 |
| `NOW_PAY_PURCHASE_LINK_CREATING` | 当前购买链接正在创建中，不允许重复提交请求 | 稍后用原 `out_request_no` 和原参数重试 |
| `NOW_PAY_PURCHASE_LINK_INVALID` | 购买链接已过期或不存在 | 确认旧购买入口失效后，按新的购买意图生成新请求号；不要将核销超时按此处理 |