开发 服务端 苹果支付 苹果支付指引
# 苹果IAP支付接入说明
更新时间:2025-04-14 11:23:59
# 一、 前置说明
# 1.1 关于接入
IAP全称是“In-App purchase”,是指苹果App Store的应用内购买,IAP是苹果为App内购买虚拟商品或服务提供的一套支付系统。IAP是在iOS客户端支付虚拟商品时必须要走的支付路径。
快手小程序接入iOS的IAP支付,相较于担保支付(单次) (opens new window),有两处变动改造点
- 使用/openapi/mp/developer/epay/iap/create_order预下单接口
- ks.pay接口增加苹果内购标识
具体信息在本文下面章节
注:IAP支付接入,仅因对iOS系统内,安卓系统无需关注,使用老的担保支付即可
# 1.2 关于退款
- 苹果内购不支持线上退款,因此没有退款请求接口。若用户有退款请求,可使用以下方式
- 商家可联系用户线下协商退款
- 引导用户至苹果客服侧申请退款
- 若退款方式为苹果客服侧退款,在苹果侧受理退款后,会将退款消息通知至快手小程序平台,平台通过退款回调(回调地址 refund_notify_url)告知开发者退款信息
# 1.3 关于订单同步
- IAP支付的订单需要进行订单同步,使用订单信息同步接口 (opens new window)
# 1.4 关于账单查询
与担保支付的账单查询接口保持一致:担保支付|账单查询能力 (opens new window)
支付方式为APPLE_PAY的订单,即为苹果支付的订单
IAP订单会在支付账单里面添加
- 订单原价
- 用户支付金额
- 平台补贴金额
- 支付渠道:APPLE_PAY
在退款账单新增:
- 支付渠道:APPLE_PAY
# 1.5 版本说明
在iOS系统中,快手11.6.50版本开始封禁小程序支付能力,无法通过微信或者支付宝支付。
在12.0.20版本中支持苹果IAP支付,因此在接入IAP支付时,需要把测试机版本升级到12.0.20及以上
# 1.6 用户端支付loading展示
平台提供默认loading展示,无需小程序开发者开发相关功能。
# 二、IAP 支付 OPEN-API
# 2.1 预下单接口
- 支付回调地址会优先使用开发者传入的 notify_url,如果接口没有传入,会填充开发者在开发者平台设置的 支付回调,该支付回调地址设置与查看步骤如下【小程序开发者平台 -> 交易管理 -> 支付管理 -> 支付设置 (opens new window) -> 默认回调地址】
- 退款回调地址会优先使用开发者传入的 refund_notify_url,如果接口没有传入,会填充开发者在开发者平台设置的 退款回调,该退款回调地址设置与查看步骤同上
# 2.1.1 基本信息
名称 | 内容 |
HTTP URL | https://open.kuaishou.com/openapi/mp/developer/epay/iap/create_order |
HTTP Method | POST |
Scope | 需要具有小程序担保支付权限(scope.ks.epay) |
# 2.1.2 请求头
名称 | 字段类型 | 内容 |
Content-Type | String | 固定值: "application/json" |
# 2.1.3 请求参数
以下字段放在 query param 处:
字段名 | 类型 | 是否必填 | 是否参与签名 | 参数位置 | 说明 |
app_id | string | 是 | 是 | query param | 小程序AppId 例如:ks707065143182458884 |
access_token | string | 是 | 否 | query param | 拥有小程序支付权限的access token,获取方式见getAccessToken |
以下字段放在 body json 处:
字段名 | 类型 | 是否必填 | 是否参与签名 | 参数位置 | 说明 |
out_order_no | string[6,32] | 是 | 是 | body json | 商户系统内部订单号,只能是数字、大小写字母_-*且在同一个商户号下唯一 示例值:1217752501201407033233368018 |
open_id | string | 是 | 是 | body json | 快手用户在当前小程序的open_id,可通过login操作获取。 |
subject | string[1,128] | 是 | 是 | body json | 商品名称或者商品描述简介,建议长度在10个汉字以内,在收银台页面、支付账单中供用户查看使用。注:不可传入特殊符号、emoji 表情等,否则会影响支付成功,1汉字=2字符。 |
detail | string[1,1024] | 是 | 是 | body json | 商品详情。注:不可传入特殊符号、emoji 表情等,否则会影响支付成功,1汉字=2字符。 |
type | number | 是 | 是 | body json | 商品类型,不同商品类目的编号见 担保支付商品类目编号 |
order_amount | number | 是 | 是 | body json | 订单原价,单位为[分],不允许传非整数的数值。 |
user_pay_amount | number | 是 | 是 | body json | 用户实际金额,单位为[分]。 1. 如果订单没有补贴,则user_pay_amount=order_amount 2. 如果订单有补贴,那么user_pay_amount 是原价基础上补贴后的价格。该金额需要匹配上苹果内购的价格档位。苹果价格档位信息,第一列为价格档位信息,第二列为苹果服务费,第三列为苹果扣除苹果税后实际结算的金额。 如果有补贴,并且补贴价格为subsidyAmount,user_pay_amount-subsidyAmount为实际折扣后价格,如果user_pay_amount-subsidyAmount 恰好等于苹果某档位,那么user_pay_amount传user_pay_amount-subsidyAmount 如果 档位A < user_pay_amount-subsidyAmount < 档位B,那么user_pay_amount传档位A或者档位B的任意值均可,由开发者自行选择。 举例: |
goods_id | string[1, 256] | 否(本地生活类必填) | 是 | body json | 下单商品id,需与商品对接时的product_id一致,长度限制256个英文字符,1个汉字=2个英文字符;短剧类,如果要用补贴,必传 |
goods_detail_url | string[1, 500] | 否(本地生活类必填) | 是 | body json | 订单详情页跳转path。长度限制500个英文字符,1个汉字=2个英文字符; 示例值:/page/index/anima |
expire_time | number | 是 | 是 | body json | 订单过期时间,单位秒,300s - 3600s |
attach | string[0,128] | 否 | 是 | body json | 开发者自定义字段,回调原样回传. 注:1汉字=2字符;勿回传敏感信息 |
notify_url | string[1, 256] | 否 | 是 | body json | 支付回调 通知URL必须为直接可访问的URL,不允许携带查询串。 |
refund_notify_url | string[1, 256] | 否 | 是 | body json | 退款回调 用户在苹果appStore发起退款后,小程序平台通知给开发者。 通知URL必须为直接可访问的URL,不允许携带查询串。 |
activity_info | string[1:128] | 否 | 是 | body json |
订单有参与平台补贴活动,则传入活动信息,否则不用传。 |
sign | string | 是 | 否 | body json | 开发者对核心字段签名, 签名方式见 附录 |
# 2.1.4 请求示例
curl --location --request POST 'https://open.kuaishou.com/openapi/mp/developer/epay/iap/create_order?app_id=ks707065143182458884&access_token=ChFvYXV0aC5hY2Nlc3NUb2tlbhJQcpTii72q9RcEb4iBAo2sQ-MNDRv4ksDSV9sA-u6yX_8BdNJRWHQxFXjdzlVph-8MGCWrzxQylHXsI6zKUKANl7tzt3O10ZK-O4UmLXmyQqcaEqr20o3-d0Tt4_ZJzk9p2G6vnyIg-5C3geR6MIqH53T7CrvtiC9nkZvAR4VU0J8kynIpi-koDzAB' \
--header 'Content-Type: application/json' \
--data-raw '{
"open_id":"5b748c61ef290140c0656638eaa0d69c",
"out_order_no":"testiap00006",
"subject":"测试描述测试iap",
"detail":"测试描述测试iap详情",
"type":"74",
"order_amount":100,
"user_pay_amount":100,
"goods_id":"1",
"goods_detail_url":"/page/index/index",
"expire_time":"300",
"attach":"iap支付demoiap支付demoiap支付demo",
"notify_url":"https://qa-mp.test.kuaishou.com/zeus/epay/notify",
"refund_notify_url": "https://qa-mp.test.kuaishou.com/zeus/epay/notify",
"sign":12333
}'
说明:iap支付预下单,和担保支付(单次)下单入参的区别是:
- 需要传入一个user_pay_amount字段,在无补贴情况下,user_pay_amount=order_amount
- user_pay_amount一定要是苹果支持的档位,否则无法支付成功
- refund_notify_url,在预下单时,需要传入退款回调url,用于用户退款时,回调通知给开发者
# 2.1.5 响应结果
返回值为 JSON 形式,其中包括如下字段:
字段名 | 类型 | 说明 |
result | number | 状态码 1-业务处理成功 非1-请求错误,具体见错误码 |
error_msg | string | 错误提示信息,常见错误处理可参考附录常见问题章节 |
order_info | json string | 拉起收银台的 orderInfo |
示例如下(仅供参考):
{
"result":1,
"error_msg":"错误信息提示",
"order_info":{
"order_no": "121072611585202788127",// 平台提供的订单号
"order_info_token": "ChJrc01wUGF5Lm9yZGVyVG9rZW4SULxOUORbNX1NAzmbs3vCE8Fo8FN8EW90EM7iReQujs85RbgDNVDPqxJoGly_jX7Zv9kwTiXsrFuSgwrR-ufuZexCYejepc-C0swHGhJtqssdzyq4aMsYYWjhyloiIOZOjlvg2cPW6VJsOmt6c4Tz2qSsZoAhTeKIZAXM13SRKAUwAQ"
}
}
# 2.1.6 错误码
当 result 不为 1 时,说明请求错误,全量错误码见附录 (opens new window)。
苹果支付预下单相关错误码如下
错误码 | 错误提示 | 解决建议 |
10000502 | 未申请开启苹果支付能力,请先在开发者后台开通 | 需要在快手小程序开发者后台,交易管理-支付管理-账户开通tab下,开通苹果支付权限。 |
10000200 | 用户实际支付金额必须大于0,且小于订单金额 | user_pay_amount参数需要大于0,且小于等于order_amount。 |
未补贴订单,用户实际支付金额需等于订单原价 | 未参与补贴订单,user_pay_amount需要和order_amount相等 | |
IAP支付下单请求参数必须有refundNotifyUrl且长度不超过356 | 请检查refund_notify_url参数是否传入,且长度是否合法 | |
10000623 | 订单用户支付金额不合法 | 订单信息中用户支付金额user_pay_amount小于0,请联系快手小程序客服支持排查 |
# 2.2 支付回调
用户支付成功后,和普通担保支付一样,有支付回调,回调信息如下:
{
"data": {
"ks_order_no": "124070401619134310455",
"channel": "APPLE_PAY",
"developer_promotion_amount": 0,
"apple_channel_fee": 47,
"order_amount": 150,
"subsidy_amount": 0,
"attach": "iap支付demoiap支付demoiap支付demo",
"app_id": "ks707065143182458884",
"out_order_no": "1720077455378iapDemo",
"sku_id": "",
"promotion_amount": 0,
"pay_time": 1720077472000,
"extra_info": "{\"url\":\"\",\"provider\":\"\",\"item_type\":\"UNKNOWN\",\"item_id\":\"\",\"author_id\":\"\",\"refer_id\":\"\",\"channel_mark\":\"\",\"provider_type\":\"\",\"trade_no\":\"2000000646912252\",\"subsidy\":0,\"upa\":150,\"rnu\":\"https://qa-mp.corp.kuaishou.com/zeus/epay/notify\",\"acf\":47,\"withhold_time\":0,\"withhold_period\":0,\"withhold_template_id\":0,\"from_standard_trade_payment\":false}",
"enable_promotion": false,
"trade_no": "2000000646912252",
"status": "SUCCESS",
"user_pay_amount": 150
},
"biz_type": "PAYMENT",
"message_id": "63ccf549-0906-408c-9111-e66d86479843",
"app_id": "ks707065143182458884",
"timestamp": 1720077476139
}
其中重点关注的几个字段如下:
字段 | 类型 | 说明 |
ks_order_no | string | 小程序小程序平台订单号 |
channel | string | 苹果支付回调固定值为「APPLE_PAY」 |
apple_channel_fee | number | 当前订单,苹果收取的苹果通道费 |
user_pay_amount | number | 用户实际支付金额 |
order_amount | number | 订单原始金额。在用户未参与补贴活动情况下,order_amount=user_pay_amount (目前小程序平台已下线补贴活动) |
status | string | 订单支付状态;取值:PROCESSING-处理中|SUCCESS-成功|FAILED-失败 |
attach | string | 预下单时携带的开发者自定义信息 |
enable_promotion | boolean | 是否参与分销,true:分销;false:非分销 |
developer_promotion_amount | number | 预计服务商分销金额,单位:分 |
promotion_amount | number | 预计达人分销金额,单位:分 |
# 2.3 结算接口
IAP支付订单与普通订单的结算能力相同,具体结算接口详见 担保支付|结算能力 (opens new window)
# 2.4 退款回调
退款流程参考1.2,用户在苹果AppStore申请退款,苹果审核通过同意退款后,回调给快手小程序平台,快手小程序平台回调退款信息给开发者。退款回调参考示例如下:
{
"data": {
"ks_order_no": "124061402132935925493",
"channel": "APPLE_PAY",
"developer_promotion_amount": 0,
"apple_channel_fee": 0,
"order_amount": 100,
"subsidy_amount": 0,
"refund_amount": 100,
"attach": "",
"app_id": "ks707065143182458884",
"refund_type": "结算前退款",
"out_refund_no": "2000000627980015",
"out_order_no": "1718336680647iapDemo",
"ks_refund_fail_reason": "用户通过苹果客服申请订单退款",
"apply_refund_reason": "用户通过苹果客服申请订单退款",
"promotion_amount": 0,
"pay_time": 0,
"enable_promotion": false,
"ks_refund_no": "224061401403754055493",
"status": "SUCCESS",
"user_pay_amount": 100
},
"biz_type": "REFUND",
"message_id": "3641e55b-dd63-4344-9276-527f0c3d54e5",
"app_id": "ks707065143182458884",
"timestamp": 1718337814608
}
重点关注如下字段
字段 | 类型 | 说明 |
ks_order_no | string | 快手小程序订单号 |
channel | string | 苹果支付回调固定值为「APPLE_PAY」 |
order_amount | number | 订单支付金额 |
refund_amount | number | 订单退款金额(对于苹果支付,只会一次性退全部订单金额) |
refund_type | string | 退款来源说明,取值为"结算前退款","结算后退款","保证金账户退款" |
ks_refund_no | string | 快手小程序退款单号 |
status | string | 退款状态,取值为PROCESSING-处理中|SUCCESS-成功|FAILED-失败 |
# 三、 JS接口
使用API: ks.pay (opens new window)
新增字段payType,仅作用于IAP支付,其他支付方式不传:
属性名 | 类型 | 值 | 是否必填 | 说明 |
payType | String | IAPPurchase | 否 | 苹果内购 |
tips:在js文件中使用ks.pay时,请勿在同页面内使用无UI支付组件(<payment-list>)
示例:
Page({
data: {
payment: {
provider: '',
provider_channel_type: '',
},
},
async pay() {
const paymentChannel = this.data.payment;
// 执行预下单逻辑
await this.doPreOrder(payment);
// 前置判断
// 当前所属平台是否为ios(iphone和ipad的platform均为ios)
const platform = ks.getSystemInfoSync().platform;
// 是否支持payType的值为IAPPurchase
const isSupportApplePay = ks.canIUse('pay.object.payType.IAPPurchase');
if(platform === 'ios' && isSupportApplePay){
// 执行支付
ks.pay({
serviceId,
orderInfo,
paymentChannel,
payType: 'IAPPurchase'
success,
fail,
})
} else {
ks.pay({
serviceId,
orderInfo,
paymentChannel,
success,
fail,
})
}
}
})