集成 PayPay Smart Payment 支付
Smart Payment 是 PayPay 推出的一款免密支付 JS SDK, 致力于优化买家的支付体验和提供支付成功率。它允许您将 PayPay 的功能集成到您的用户界面中,在获取买家授权后,买家在后续支付无需跳转 PayPay 应用即可完成支付。
用户体验
以下为首次支付和后续支付的用户体验:
首次支付
后续支付
体验差异
首次支付和后续支付的用户体验在 Web/WAP 端集成上没有差别,在移动端的差别如下:
支付流程
以下分别为首次支付和后续支付流程示意图:
首次支付
后续支付


集成准备
- 已获得 client ID。
- 已完成密钥配置。
- 已完成异步通知接收地址的配置。
- 集成服务端 SDK 资源包,并完成接口库安装及请求示例初始化。具体操作请参阅服务端 SDK。
为保障支付流程的兼容性与安全性,以下列出了各浏览器及应用的最低版本要求,其中商户 WebView 和 PayPay 应用需运行在指定的系统版本及以上环境:
- 浏览器版本要求:
- 商户 WebView 需支持 iOS 11 或以上、Android 4.4(API level 19)或以上。
- PayPay 应用需运行于 iOS 16 或以上、Android 9 或以上。
支付集成
开始集成,请按照以下步骤操作:
- 创建支付订单
- 获取跳转支付推进链接
- 接收异步通知
步骤 1:创建支付订单 服务端
调用 pay(单笔支付)接口,在请求中指定 paymentMethod.paymentMethodType 为
PAYPAY
,同时设置 paymentMethod.paymentMethodMetadata.smartPaymentEnabled 为 true
。注意:
- 首次支付和后续支付均需调用 pay(单笔支付)接口,并跳转返回的支付推进链接 (normalUrl)。
- 商户侧传入的 paymentRedirectUrl 必须是 https:// 开头。
以下代码展示了请求报文的示例:
JSON
{
"order": {
"env": {
"osType": "IOS",
"terminalType": "APP"
},
"orderAmount": {
"currency": "JPY",
"value": "1825"
},
"orderDescription": "TEST.COM",
"referenceOrderId": "TEST4754300929"
},
"paymentAmount": {
"currency": "JPY",
"value": "1825"
},
"paymentMethod": {
"paymentMethodMetadata": "{"smartPaymentEnabled":true}",
"paymentMethodType": "PAYPAY"
},
"paymentNotifyUrl": "https://www.yourwebsite.com/notify/channel/notify",
"paymentRedirectUrl": "https://www.yourwebsite.com/redirect",
"paymentRequestId": "TEST4754300929",
"productCode": "CASHIER_PAYMENT",
"settlementStrategy": {
"settlementCurrency": "JPY"
}
}Antom 收到请求后会返回对应的 PayPay 支付推进链接(normalUrl),示例代码如下:
JSON
{
"normalUrl": "https://ac.alipay.com/page/antom-web-checkout-v2/payment-transition/pages/paypay/index.html?orderInfo=***test",
"paymentActionForm": "{"method":"GET","paymentActionFormType":"RedirectActionForm","redirectUrl":"https://ac.alipay.com/page/antom-web-checkout-v2/payment-transition/pages/paypay/index.html?orderInfo=***test"}",
"paymentAmount": {
"currency": "JPY",
"value": "1825"
},
"paymentCreateTime": "2025-09-16T20:48:47-07:00",
"paymentId": "20250917******450216341557",
"paymentRequestId": "PAYMENT_202*****46357_AUTO",
"redirectActionForm": {
"method": "GET",
"redirectUrl": "https://ac.alipay.com/page/antom-web-checkout-v2/payment-transition/pages/paypay/index.html?orderInfo=***test"
},
"result": {
"resultCode": "PAYMENT_IN_PROCESS",
"resultMessage": "payment in process",
"resultStatus": "U"
}
}步骤 2:获取跳转支付推进链接 客户端
Web/WAP
iOS
Android
Web 端和 WAP 端可直接跳转 normalUrl,示例代码如下:
JavaScript
window.location.href = pay.response.normalUrl;注意:首次支付和后续支付均跳转 normalUrl 即可,Antom 会根据买家是否在浏览器中存储了支付信息来决策展示支付授权页(首次支付时)或半屏支付确认页(后续支付时)。
按照以下步骤处理 Antom 返回的支付推进链接 (normalUrl):
1. 拼接参数
iOS 端不能直接跳转 normalUrl,需要在 normalUrl 后拼接 source=embedded 参数,然后用 WebView 进行加载,示例如下:
https://ac.alipay.com/page/antom-web-checkout-v2/payment-transition/pages/paypay/index.html?orderInfo=Y2xpZW50SWQ9YV90M0I0ZERrRG1HJm1lcmNoYW50SWQ9MTg4QzBFR2tQWlhhRDN4dHFMZXVuRFM4UXdpbXU4YWR2V09Pc2VycFpWcWE3bz0mcGF5bWVudFJlcXVlc3RJZD1oNWtnZDdyQ0U0Nm91ZDJjdHhVcE5MSzZjOUpwRkR6M2VLVEsyTDQ0bFBjPSZtZXJjaGFudEFsaWFzPTkxODQ2MDc2MDQyMDU1NjgwMCZjaGFubmVsUGF5bWVudElkPTc0ODE3MjczNjM0NTYzJmFtb3VudD0zMDAmY3VycmVuY3k9SlBZJm1lcmNoYW50UmVkaXJlY3RVcmw9aHR0cHMlM0ElMkYlMkZwc3AuYWMuYWxpcGF5LmNvbSUyRnBhZ2UlMkZzaW11bGF0aW9uLXdhbGxldCUyRmFjd2FsbGV0JTJGYWxpcGF5Y29ubmVjdGNvZGUuaHRtbCZwYXltZW50UmVkaXJlY3RVcmw9aHR0cHMlM0ElMkYlMkZvcGVuLW5hLmFsaXBheS5jb20lMkZhcGklMkZvcGVuJTJGdXJsX2NhbGxiYWNrX3Nob3J0X2dldCUyRnNicHMlMkZ1cmxDYWxsYmFjay5odG0lM0ZzaWduRGF0YSUzREZFZDBhRGN6VHp6WTVzSlo3NVNtV3ZSUTRRcyUyNTNEJTI2aW5TZXJpYWxObyUzRDIwMjUwOTE3ODkwMzEzMDAwMDg1NTYxMTU1NDM2NTYlMjZvdXRPcmRlck5vJTNENzQ4MTcyNzM2MzQ1NjM=®ion=SG&source=embedded2. WebView 拦截与外跳
注意:如您需要使用 PayPay 的沙箱钱包,请联系 Antom 技术支持做额外报备。
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
NSURL *url = navigationAction.request.URL;
NSString *urlString = url.absoluteString;
if ([urlString containsString:@"antom_sanbox"]) {
NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:NO];
NSMutableDictionary *queryParameters = [NSMutableDictionary dictionary];
// 检查 URL 是否有查询项
if (components.queryItems) {
// 遍历所有的查询项
for (NSURLQueryItem *item in components.queryItems) {
if (item.value) {
// 将参数名(name)和参数值(value)添加到字典中
queryParameters[item.name] = item.value;
}
}
}
NSString *isDeeplinkUrl = queryParameters[@"isDeeplinkUrl"];
if (isDeeplinkUrl && [isDeeplinkUrl length] > 0 && isDeeplinkUrl == @"true") {
[[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
decisionHandler(WKNavigationActionPolicyCancel);
return;
}
}
if ([urlString containsString:@"www.sandbox.paypay"] || [urlString containsString:@"www.paypay.ne.jp"]) {
NSLog(@"Intermediate page/中间页");
NSLog(@"Merchant handles the subsequent logic/商户自己处理后续逻辑");
if (url) {
// 使用 UIApplication.shared.open 打开 URL
[[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
}
decisionHandler(WKNavigationActionPolicyCancel);
return;
}
decisionHandler(WKNavigationActionPolicyAllow);
}3. 获取 paypayRedirectUrl 和 one_time_token 后进行二次跳转
PayPay 回跳商户页面后获取 paypayRedirectUrl 和 one_time_token。买家授权完成后会回跳商户的 paymentRedirectUrl,PayPay 在此链接(URL)后拼接 paypayRedirectUrl 和 one_time_token 两个参数,示例如下:
https://www.yourwebsite.com/ltspc/pay/callback/deeplink?paypayRedirectUrl=https%253A%252F%252Fac.alipay.com%252Fpage%252Fantom-web-checkout-v2%252Fpayment-transition%252Fpages%252Fpaypay%252Findex.html%253ForderInfo%253DY2xpZW50SWQ9YV90M0I0ZERrRG1HJm1lcmNoYW50SWQ9MTg4QzBFR2tQWlhhRDN4dHFMZXVuRFM4UXdpbXU4YWR2V09Pc2VycFpWcWE3bz0mcGF5bWVudFJlcXVlc3RJZD1wemFtMXk1NWlCWXdnVDhNQUpFK0tYVjlyMDQ5L0ZFQjBSY01DUWpXMlhvPSZtZXJjaGFudEFsaWFzPTkxODQ2MDc2MDQyMDU1NjgwMCZjaGFubmVsUGF5bWVudElkPTUwMzg1MzA0MzM2OTMxJmFtb3VudD0xMCZjdXJyZW5jeT1KUFkmbWVyY2hhbnRSZWRpcmVjdFVybD1odHRwcyUzQSUyRiUyRnByZS5hYy5hbGlwYXkuY29tJTJGcGFnZSUyRmFudG9tX3NhbmJveCUyRnJlZGlyZWN0Lmh0bWwlM0Z1cmwlM0RrYWRlbW8lM0ElMkYlMkZzZXR0aW5nJTJGcGF0aCUyNmF1dG8lM0QwJnBheW1lbnRSZWRpcmVjdFVybD1odHRwcyUzQSUyRiUyRm9wZW4tbmEuYWxpcGF5LmNvbSUyRmFwaSUyRm9wZW4lMkZ1cmxfY2FsbGJhY2tfc2hvcnRfZ2V0JTJGc2JwcyUyRnVybENhbGxiYWNrLmh0bSUzRnNpZ25EYXRhJTNEM0gxUVpFRUNFSzNMSkRkUnBCZm5XaWpSZnFvJTI1M0QlMjZpblNlcmlhbE5vJTNEMjAyNTEwMjM4OTAzMTMwMDAwOTc2OTYxNTM1MjkxNiUyNm91dE9yZGVyTm8lM0Q1MDM4NTMwNDMzNjkzMQ%25253D%25253D%2526region%253DSG%2526source%253Dembedded%2526isAuthorized%253Dtrue&one_time_token=2bdae7ec-9d3a-4636-9662-05fbdcf3e9f6&ppSmartPayment=1paypayRedirectUrl 和 one_time_token 两个参数的提取以及 URL 解码的示例代码如下:
Objective-C
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler {
if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) {
NSURL *url = userActivity.webpageURL;
NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:NO];
// 替换为paymentRedirectUrl中的host
if ([components.host isEqualToString:@"psp.ac.alipay.com"]) {
NSMutableDictionary *queryParameters = [NSMutableDictionary dictionary];
// 检查 URL 是否有查询项
if (components.queryItems) {
// 遍历所有的查询项
for (NSURLQueryItem *item in components.queryItems) {
if (item.value) {
// 将参数名(name)和参数值(value)添加到字典中
queryParameters[item.name] = item.value;
}
}
}
NSString *paypayRedirectUrl = queryParameters[@"paypayRedirectUrl"];
if (paypayRedirectUrl && [paypayRedirectUrl length] > 0) {
paypayRedirectUrl = [paypayRedirectUrl stringByRemovingPercentEncoding];
// 拼接 PayPay 参数
NSString *refreshUrl = [NSString stringWithFormat:@"%@&one_time_token=%@&ppSmartPayment=1", queryParameters[@"paypayRedirectUrl"], queryParameters[@"one_time_token"]];
// 重新刷新或打开支付页,此支付页面不会拉起 PayPay 应用,您需自行使用 WebView 加载拼接好的 paypayRedirectUrl
}
}
return true;
}当商户中间页拉起商户应用时,请勿丢失 paypayRedirectUrl 和 one_time_token 两个参数。在获取需二次跳转的链接后,您可通过 WebView 重新加载该链接(如代码第 25 行注释所注)。以下示例展示了需要二次跳转的链接,且该链接已经在 paypayRedirectUrl 后方拼接了 one_time_token:
需二次跳转的链接
https://ac.alipay.com/page/antom-web-checkout-v2/payment-transition/pages/paypay/index.html?orderInfo=Y2xpZW50SWQ9YV90M0I0ZERrRG1HJm1lcmNoYW50SWQ9MTg4QzBFR2tQWlhhRDN4dHFMZXVuRFM4UXdpbXU4YWR2V09Pc2VycFpWcWE3bz0mcGF5bWVudFJlcXVlc3RJZD1wemFtMXk1NWlCWXdnVDhNQUpFK0tlMlY1MVh6eSt2TWxMd2V3NlYrN0s0PSZtZXJjaGFudEFsaWFzPTkxODQ2MDc2MDQyMDU1NjgwMCZjaGFubmVsUGF5bWVudElkPTUwMzg1NTQwMTY1MjUwJmFtb3VudD0xMCZjdXJyZW5jeT1KUFkmbWVyY2hhbnRSZWRpcmVjdFVybD1odHRwcyUzQSUyRiUyRnByZS5hYy5hbGlwYXkuY29tJTJGcGFnZSUyRmFudG9tX3NhbmJveCUyRnJlZGlyZWN0Lmh0bWwlM0Z1cmwlM0RrYWRlbW8lM0ElMkYlMkZzZXR0aW5nJTJGcGF0aCUyNmF1dG8lM0QwJnBheW1lbnRSZWRpcmVjdFVybD1odHRwcyUzQSUyRiUyRm9wZW4tbmEuYWxpcGF5LmNvbSUyRmFwaSUyRm9wZW4lMkZ1cmxfY2FsbGJhY2tfc2hvcnRfZ2V0JTJGc2JwcyUyRnVybENhbGxiYWNrLmh0bSUzRnNpZ25EYXRhJTNEQUhrTVdMOHpUd1clMjUyQmtXcGNFaG14UHJrSHk0SSUyNTNEJTI2aW5TZXJpYWxObyUzRDIwMjUxMDIzODkwMzEzMDAwMDkxNDEzMjAyNDY0OTYlMjZvdXRPcmRlck5vJTNENTAzODU1NDAxNjUyNTA%3D®ion=SG&source=embedded&isAuthorized=true&one_time_token=4f4c7877-553b-438c-9739-d64109a2bd66&ppSmartPayment=14. 支付后处理
支付完成后会再次跳转到商户首次设置的 paymentRedirectUrl,此时 H5 将根据服务端结果展示支付结果,不会在 paymentRedirectUrl 上额外拼接参数。
按照以下步骤处理 Antom 返回的支付推进链接 (normalUrl):
1. 拼接参数
Android 端不能直接跳转 normalUrl,需要在 normalUrl 后拼接 source=embedded 参数,然后用 WebView 进行加载,示例如下:
https://ac.alipay.com/page/antom-web-checkout-v2/payment-transition/pages/paypay/index.html?orderInfo=Y2xpZW50SWQ9YV90M0I0ZERrRG1HJm1lcmNoYW50SWQ9MTg4QzBFR2tQWlhhRDN4dHFMZXVuRFM4UXdpbXU4YWR2V09Pc2VycFpWcWE3bz0mcGF5bWVudFJlcXVlc3RJZD1oNWtnZDdyQ0U0Nm91ZDJjdHhVcE5MSzZjOUpwRkR6M2VLVEsyTDQ0bFBjPSZtZXJjaGFudEFsaWFzPTkxODQ2MDc2MDQyMDU1NjgwMCZjaGFubmVsUGF5bWVudElkPTc0ODE3MjczNjM0NTYzJmFtb3VudD0zMDAmY3VycmVuY3k9SlBZJm1lcmNoYW50UmVkaXJlY3RVcmw9aHR0cHMlM0ElMkYlMkZwc3AuYWMuYWxpcGF5LmNvbSUyRnBhZ2UlMkZzaW11bGF0aW9uLXdhbGxldCUyRmFjd2FsbGV0JTJGYWxpcGF5Y29ubmVjdGNvZGUuaHRtbCZwYXltZW50UmVkaXJlY3RVcmw9aHR0cHMlM0ElMkYlMkZvcGVuLW5hLmFsaXBheS5jb20lMkZhcGklMkZvcGVuJTJGdXJsX2NhbGxiYWNrX3Nob3J0X2dldCUyRnNicHMlMkZ1cmxDYWxsYmFjay5odG0lM0ZzaWduRGF0YSUzREZFZDBhRGN6VHp6WTVzSlo3NVNtV3ZSUTRRcyUyNTNEJTI2aW5TZXJpYWxObyUzRDIwMjUwOTE3ODkwMzEzMDAwMDg1NTYxMTU1NDM2NTYlMjZvdXRPcmRlck5vJTNENzQ4MTcyNzM2MzQ1NjM=®ion=SG&source=embedded2. WebView 拦截与外跳
注意:如您需要使用 PayPay 的沙箱钱包,请联系 Antom 技术支持做额外报备。
public class WebViewActivity extends AppCompatActivity {
private WebView webView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_demo_web_view);
webView = findViewById(R.id.webView);
webView.setWebViewClient(new MyWebViewClient());
}
private class MyWebViewClient extends WebViewClient {
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
String url = "";
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
url = request.getUrl().toString();
} else {
url = request.toString();
}
Uri parsedUri = Uri.parse(url);
if (parsedUri.toString().contains("antom_sanbox")) {
Bundle queryParameters = new Bundle();
for (String key : parsedUri.getQueryParameterNames()) {
queryParameters.putString(key, parsedUri.getQueryParameter(key));
}
boolean isDeeplinkUrl = Objects.equals(queryParameters.getString("isDeeplinkUrl"), "true");
if (isDeeplinkUrl) {
// 在外部浏览器中打开链接
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(intent);
return true;
}
}
if (url.contains("www.sandbox.paypay") || url.contains("www.paypay.ne.jp") {
Log.d(TAG, "Intermediate page/中间页");
Log.d(TAG, "Merchant handles the subsequent logic/商户自己处理后续逻辑");
try {
Intent intent = new Intent(Intent.ACTION_VIEW, parsedUri);
startActivity(intent);
} catch (Exception e) {
// e.printStackTrace();
}
return true;
}
return false;
}
}
}3. 获取 paypayRedirectUrl 和 one_time_token 后进行二次跳转
PayPay 回跳商户页面后获取 paypayRedirectUrl 和 one_time_token。买家授权完成后会回跳商户的 paymentRedirectUrl,PayPay 在此链接(URL)后拼接 paypayRedirectUrl 和 one_time_token 两个参数,示例如下:
https://www.yourwebsite.com/ltspc/pay/callback/deeplink?paypayRedirectUrl=https%253A%252F%252Fac.alipay.com%252Fpage%252Fantom-web-checkout-v2%252Fpayment-transition%252Fpages%252Fpaypay%252Findex.html%253ForderInfo%253DY2xpZW50SWQ9YV90M0I0ZERrRG1HJm1lcmNoYW50SWQ9MTg4QzBFR2tQWlhhRDN4dHFMZXVuRFM4UXdpbXU4YWR2V09Pc2VycFpWcWE3bz0mcGF5bWVudFJlcXVlc3RJZD1wemFtMXk1NWlCWXdnVDhNQUpFK0tYVjlyMDQ5L0ZFQjBSY01DUWpXMlhvPSZtZXJjaGFudEFsaWFzPTkxODQ2MDc2MDQyMDU1NjgwMCZjaGFubmVsUGF5bWVudElkPTUwMzg1MzA0MzM2OTMxJmFtb3VudD0xMCZjdXJyZW5jeT1KUFkmbWVyY2hhbnRSZWRpcmVjdFVybD1odHRwcyUzQSUyRiUyRnByZS5hYy5hbGlwYXkuY29tJTJGcGFnZSUyRmFudG9tX3NhbmJveCUyRnJlZGlyZWN0Lmh0bWwlM0Z1cmwlM0RrYWRlbW8lM0ElMkYlMkZzZXR0aW5nJTJGcGF0aCUyNmF1dG8lM0QwJnBheW1lbnRSZWRpcmVjdFVybD1odHRwcyUzQSUyRiUyRm9wZW4tbmEuYWxpcGF5LmNvbSUyRmFwaSUyRm9wZW4lMkZ1cmxfY2FsbGJhY2tfc2hvcnRfZ2V0JTJGc2JwcyUyRnVybENhbGxiYWNrLmh0bSUzRnNpZ25EYXRhJTNEM0gxUVpFRUNFSzNMSkRkUnBCZm5XaWpSZnFvJTI1M0QlMjZpblNlcmlhbE5vJTNEMjAyNTEwMjM4OTAzMTMwMDAwOTc2OTYxNTM1MjkxNiUyNm91dE9yZGVyTm8lM0Q1MDM4NTMwNDMzNjkzMQ%25253D%25253D%2526region%253DSG%2526source%253Dembedded%2526isAuthorized%253Dtrue&one_time_token=2bdae7ec-9d3a-4636-9662-05fbdcf3e9f6&ppSmartPayment=1paypayRedirectUrl 和 one_time_token 两个参数的提取以及 URL 解码的示例代码如下:
/**
* 当Activity接收到新的Intent时调用
* @param intent 新的Intent
*/
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
if (Intent.ACTION_VIEW.equals(intent.getAction())) {
Uri uri = intent.getData();
if (uri == null) {
return;
}
if (uri.getHost() == null) {
return;
}
// 替换为paymentRedirectUrl中的host
if ( uri.getHost().equals("psp.ac.alipay.com")) {
Bundle queryParameters = new Bundle();
// 遍历所有的查询项
for (String key : uri.getQueryParameterNames()) {
// 将参数名(name)和参数值(value)添加到字典中
queryParameters.putString(key, uri.getQueryParameter(key));
}
String paypayRedirectUrl = queryParameters.getString("paypayRedirectUrl");
if (queryParameters.getString("paypayRedirectUrl") != null&& !Objects.requireNonNull(paypayRedirectUrl).isEmpty()) {
try {
// 拼接 PayPay 参数
String paypayRedirectUrl = queryParameters.getString("paypayRedirectUrl");
String decodedUriString = URLDecoder.decode(paypayRedirectUrl, "UTF-8");
String refreshUrl = decodedUriString + "&one_time_token=" + queryParameters.getString("one_time_token") + "&ppSmartPayment=1";
// 重新刷新或打开支付页,此支付页面不会拉起 PayPay 应用,您需自行使用 WebView 加载拼接好的 paypayRedirectUrl
} catch (Exception e) {
Log.d(TAG, "handleIntent: ", e);
}
}
}
}
}
当商户中间页拉起商户应用时,请勿丢失 paypayRedirectUrl 和 one_time_token 两个参数。在获取需二次跳转的链接后,您可通过 WebView 重新加载该链接(如代码第 35 行注释所注)。以下示例展示了需要二次跳转的链接,且该链接已经在 paypayRedirectUrl 后方拼接了 one_time_token:
注意:首次支付且买家授权成功,PayPay 需拼接 paypayRedirectUrl 和 one_time_token 两个参数,后续支付则不会有这两个参数,因此 PayPay 不需要在链接中拼接这两个参数。
https://ac.alipay.com/page/antom-web-checkout-v2/payment-transition/pages/paypay/index.html?orderInfo=Y2xpZW50SWQ9YV90M0I0ZERrRG1HJm1lcmNoYW50SWQ9MTg4QzBFR2tQWlhhRDN4dHFMZXVuRFM4UXdpbXU4YWR2V09Pc2VycFpWcWE3bz0mcGF5bWVudFJlcXVlc3RJZD1wemFtMXk1NWlCWXdnVDhNQUpFK0tlMlY1MVh6eSt2TWxMd2V3NlYrN0s0PSZtZXJjaGFudEFsaWFzPTkxODQ2MDc2MDQyMDU1NjgwMCZjaGFubmVsUGF5bWVudElkPTUwMzg1NTQwMTY1MjUwJmFtb3VudD0xMCZjdXJyZW5jeT1KUFkmbWVyY2hhbnRSZWRpcmVjdFVybD1odHRwcyUzQSUyRiUyRnByZS5hYy5hbGlwYXkuY29tJTJGcGFnZSUyRmFudG9tX3NhbmJveCUyRnJlZGlyZWN0Lmh0bWwlM0Z1cmwlM0RrYWRlbW8lM0ElMkYlMkZzZXR0aW5nJTJGcGF0aCUyNmF1dG8lM0QwJnBheW1lbnRSZWRpcmVjdFVybD1odHRwcyUzQSUyRiUyRm9wZW4tbmEuYWxpcGF5LmNvbSUyRmFwaSUyRm9wZW4lMkZ1cmxfY2FsbGJhY2tfc2hvcnRfZ2V0JTJGc2JwcyUyRnVybENhbGxiYWNrLmh0bSUzRnNpZ25EYXRhJTNEQUhrTVdMOHpUd1clMjUyQmtXcGNFaG14UHJrSHk0SSUyNTNEJTI2aW5TZXJpYWxObyUzRDIwMjUxMDIzODkwMzEzMDAwMDkxNDEzMjAyNDY0OTYlMjZvdXRPcmRlck5vJTNENTAzODU1NDAxNjUyNTA%3D®ion=SG&source=embedded&isAuthorized=true&one_time_token=4f4c7877-553b-438c-9739-d64109a2bd66&ppSmartPayment=14. 支付后处理
支付完成后会再次跳转到商户首次设置的 paymentRedirectUrl,此时 H5 将根据服务端结果展示支付结果,不会在 paymentRedirectUrl 上额外拼接参数。
注意:
步骤 3:接收异步通知 服务端
完成支付或支付失败时,Antom 会通过 pay(单笔支付)接口中的参数 paymentNotifyUrl 指定的地址发送异步通知(notifyPayment)。具体操作参阅支付结果异步通知。
异步通知详情请见以下表格:首次支付将返回授权及支付结果,后续支付仅返回支付结果。以下是常见场景:
Antom 提供发送异步通知的功能,同时也支持通过调用 inquiryPayment 接口主动查询支付结果。
支付成功
支付失败
支付成功异步通知示例代码如下:
{
"actualPaymentAmount": {
"currency": "JPY",
"value": "10"
},
"notifyType": "PAYMENT_RESULT",
"paymentAmount": {
"currency": "JPY",
"value": "10"
},
"paymentCreateTime": "2025-11-04T03:03:23-08:00",
"paymentId": "20251104194010800100188370226536257",
"paymentRequestId": "PAYMENT_20251104190322542_AUTO",
"paymentResultInfo": {},
"paymentTime": "2025-11-04T03:07:20-08:00",
"result": {
"resultCode": "SUCCESS",
"resultMessage": "success.",
"resultStatus": "S"
}
}支付失败异步通知示例代码如下:
{
"actualPaymentAmount": {
"currency": "JPY",
"value": "10"
},
"notifyType": "PAYMENT_RESULT",
"paymentAmount": {
"currency": "JPY",
"value": "10"
},
"paymentCreateTime": "2025-10-21T19:30:26-07:00",
"paymentId": "20251022194010800100188520223208649",
"paymentRequestId": "PAYMENT_20251022103025254_AUTO",
"result": {
"resultCode": "ORDER_IS_CLOSED",
"resultMessage": "The order is closed.",
"resultStatus": "F"
}
}最佳实践
根据买家移动端是否安装 PayPay 钱包应用,系统会提供不同的后续操作:
iOS
Android
以下代码展示了 iOS 应用中如何利用 WebView 加载网页,并根据不同的支付场景智能处理跳转逻辑:
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
NSURL *url = navigationAction.request.URL;
NSString *urlString = url.absoluteString;
// 使用 Antom 沙箱环境钱包(与 PayPay 沙箱环境钱包 2 选 1)
if ([urlString containsString:@"antom_sanbox"]) {
NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:NO];
NSMutableDictionary *queryParameters = [NSMutableDictionary dictionary];
// 检查 URL 是否有查询项
if (components.queryItems) {
// 遍历所有的查询项
for (NSURLQueryItem *item in components.queryItems) {
if (item.value) {
// 将参数名(name)和参数值(value)添加到字典中
queryParameters[item.name] = item.value;
}
}
}
NSString *isDeeplinkUrl = queryParameters[@"isDeeplinkUrl"];
if (isDeeplinkUrl && [isDeeplinkUrl length] > 0 && isDeeplinkUrl == @"true") {
NSURL *sandboxUrl = [NSURL URLWithString:@"alipayconnect://"];
if (sandboxUrl && [[UIApplication sharedApplication] canOpenURL:sandboxUrl]) {
[[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
decisionHandler(WKNavigationActionPolicyCancel);
return;
} else {
decisionHandler(WKNavigationActionPolicyAllow);
return;
}
}
}
// 使用 PayPay 沙箱环境钱包(与 Antom 沙箱环境钱包 2 选 1)
if (([urlString containsString:@"www.sandbox.paypay"] || [urlString containsString:@"www.paypay.ne.jp"])) {
if (url && [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"paypay://"]]) {
// 使用 UIApplication.shared.open 打开 URL
[[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
decisionHandler(WKNavigationActionPolicyCancel);
return;
} else {
decisionHandler(WKNavigationActionPolicyAllow);
return;
}
}
// 替换为 paymentRedirectUrl 中的 host
if ([urlString containsString:@"psp.ac.alipay.com"]) {
NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:NO];
NSMutableDictionary *queryParameters = [NSMutableDictionary dictionary];
// 检查 URL 是否有查询项
if (components.queryItems) {
// 遍历所有的查询项
for (NSURLQueryItem *item in components.queryItems) {
if (item.value) {
// 将参数名(name)和参数值(value)添加到字典中
queryParameters[item.name] = item.value;
}
}
}
NSString *paypayRedirectUrl = queryParameters[@"paypayRedirectUrl"];
if (paypayRedirectUrl && [paypayRedirectUrl length] > 0) {
paypayRedirectUrl = [paypayRedirectUrl stringByRemovingPercentEncoding];
// 拼接 PayPay 参数,重新刷新或打开支付页
NSString *refreshUrl = [NSString stringWithFormat:@"%@&one_time_token=%@&ppSmartPayment=1", queryParameters[@"paypayRedirectUrl"], queryParameters[@"one_time_token"]];
decisionHandler(WKNavigationActionPolicyCancel);
// 重新刷新或打开支付页,此支付页面不会拉 PayPay 应用
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:refreshUrl]];
[self.webView loadRequest:request];
return;
}
decisionHandler(WKNavigationActionPolicyAllow);
return;
}
decisionHandler(WKNavigationActionPolicyAllow);
}
除了参考上述代码判断是否安装支付应用外,还需要在 Info.plist 配置文件中添加 LSApplicationQueriesSchemes 字段,用于声明可被查询的 URL Scheme。
注意:Info.plist 中可配置的 Scheme 数量是有限制的。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>paypay</string>
<string>alipayconnect</string>
</array>
</dict>
</plist>
以下代码展示了 Android 应用中如何利用 WebView 加载网页,并根据不同的支付场景智能处理跳转逻辑:
public class WebViewActivity extends AppCompatActivity {
private WebView webView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_demo_web_view);
webView = findViewById(R.id.webView);
webView.setWebViewClient(new MyWebViewClient());
}
private class MyWebViewClient extends WebViewClient {
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
String url = "";
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
url = request.getUrl().toString();
} else {
url = request.toString();
}
Uri parsedUri = Uri.parse(url);
// 使用 Antom 沙箱环境钱包(与 PayPay 沙箱环境钱包 2 选 1)
if (parsedUri.toString().contains("antom_sanbox")) {
Bundle queryParameters = new Bundle();
for (String key : parsedUri.getQueryParameterNames()) {
queryParameters.putString(key, parsedUri.getQueryParameter(key));
}
boolean isDeeplinkUrl = Objects.equals(queryParameters.getString("isDeeplinkUrl"), "true");
if (isDeeplinkUrl) {
Intent schemeIntent = createSchemeIntent("alipayconnect://platformapi");
if (schemeIntent != null && isAppIsInstalled(schemeIntent)) {
// 在外部浏览器中打开链接
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(intent);
} else {
webView.loadUrl(url);
}
return true;
}
}
// 使用 PayPay 沙箱环境钱包(与 Antom 沙箱环境钱包 2 选 1)
if (url.contains("www.sandbox.paypay") || url.contains("www.paypay.ne.jp") {
Intent schemeIntent = createSchemeIntent("paypay://");
if (schemeIntent != null && isAppIsInstalled(schemeIntent)) {
try {
Intent intent = new Intent(Intent.ACTION_VIEW, parsedUri);
startActivity(intent);
} catch (Exception e) {
e.printStackTrace();
}
return true;
} else {
webView.loadUrl(url);
}
return true;
}
if (parsedUri != null && parsedUri.getHost().equals("psp.ac.alipay.com")) {
Bundle queryParameters = new Bundle();
// 遍历所有的查询项
for (String key : parsedUri.getQueryParameterNames()) {
// 将参数名(name)和参数值(value)添加到字典中
queryParameters.putString(key, parsedUri.getQueryParameter(key));
}
if (queryParameters.getString("paypayRedirectUrl") != null) {
try {
// 拼接 PayPay 参数
String paypayRedirectUrl = queryParameters.getString("paypayRedirectUrl");
String decodedUriString = URLDecoder.decode(paypayRedirectUrl, "UTF-8");
String refreshUrl = decodedUriString + "&one_time_token=" + queryParameters.getString("one_time_token") + "&ppSmartPayment=1";
// 重新刷新或打开支付页,此支付页面不会拉 PayPay 应用
webView.loadUrl(refreshUrl);
} catch (Exception e) {
Log.d(TAG, "handleIntent: ", e);
}
}
}
return super.shouldOverrideUrlLoading(view, request);
}
}
/**
* 创建scheme intent
* @param url scheme url
* @return Intent对象
*/
private Intent createSchemeIntent(String url) {
Intent intent;
try {
intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME);
intent.addCategory("android.intent.category.BROWSABLE");
intent.setComponent(null);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
intent.setSelector(null);
}
} catch (URISyntaxException e) {
showToast(LoadWebViewActivity.this,
"The third-party app is not installed!
您所打开的第三方App未安装!");
}
return intent;
}按以下代码判断第三方 App 是否已安装:
/**
* 判断第三方App是否已安装
*
* @param intent Intent对象
* @return 是否已安装
*/
private boolean isAppIsInstalled(Intent intent) {
try {
List<ResolveInfo> resolves = getPackageManager().queryIntentActivities(intent, 0);
return !resolves.isEmpty();
} catch (Exception e) {
return false;
}
}
}为了遵守 Android 系统的隐私与安全策略,需要在 AndroidManifest.xml 中添加
<queries>
标签,并在其中配置支付应用的包名,以确保支付跳转链接能够正常调用对应的支付方式应用。
<queries>
<package android:name="jp.ne.paypay.android.app" />
<package android:name="com.iap.linker_portal" />
</queries>



