开发者文档
- PayPal开发者中心,注册登录https://developer.paypal.com/home
- iOS SDK集成文档 https://developer.paypal.com/docs/checkout/advanced/ios/
- iOS 官方Demo https://github.com/paypal/paypal-ios
- 开发者控制台https://developer.paypal.com/dashboard
附上几张支付过程的截图
1121714459190_.pic.jpg
2.png
1131714459190_.pic.jpg
1141714459190_.pic.jpg
1151714459190_.pic.jpg
1161714459190_.pic.jpg
一. 账号的配置
1. 在开发者控制台选择 Apps & Credentials
WX20240429-195206@2x.png2. 可以选择Create APP,或者直接使用系统默认的Default Application,点击Default Application进入详情
1. API credentials
1.png
- ClientID发起支付请求需要这个去初始化
- Secret key 生成Authentication的时候需要
2. Sandbox account info
2.png
- 更多收付款账号,点击这里
5.png
6.png
这边会有默认的收付款账号,当然还可以自己创建
@personal.example.com结尾 - 付款 - 【发起支付请求时候登录该账号付款,之前付款一直用自己注册Paypal账号,而不是沙盒里的账号,导致一直登录不成功,一般测试都是在Sandbox环境】
@business.example.com结尾 - 收款 - 创建订单的时候3. Features
3.png
这里主要勾选[Log in with PayPal],[Native Checkout SDK],再点击[Log in with PayPal]的Advanced Settings去配置
- Return URL 目前Paypal固定后缀格式:xxx.xxx.xx://paypalpay,一般xxx.xxx.xx设置为当前App的包名(eg:com.PayPalAPP://paypalpay)
- Full name和Email勾选,Privacy policy URL和User agreement URL随便填写给地址就行
- PayPal account ID (payer ID)勾选
- 最底部的Enable customers who have not yet confirmed their email with PayPal to log in to your app.勾选
4. Sandbox Webhooks,可以配置支付完成Paypal通知我们后台的回调URL,后台开发去关注即可
二. 代码集成
文档中有三种拉起支付的方式 Card、Native payments、Web payments,具体区别查阅https://developer.paypal.com/docs/checkout/advanced/ios/集成文档,这里展示下Native payments集成方式,吐槽下,官方集成文档跟官方Demo演示的流程对不上,文档上Native payments的登录是SDK内部实现,实际跑起来,登录是APP内拉系统浏览器去登录的
pod 'PayPal/PayPalNativePayments
import PayPal
let config = CoreConfig(clientID: "CLIENT_ID", environment: .sandbox)
let payPalNativeClient = PayPalNativeCheckoutClient(config: config)
- CLIENT_ID 替换成自己的clientID**
- 发起支付
@objc func payPalButtonTapped() {
Task {
let orderID = "OrderID"
let request = PayPalNativeCheckoutRequest(orderID: orderID)
await self.payPalClient.start(request: request)
}
}
- 这里的Task必须加上,要不然会崩溃,这里是参考官方Demo的写法
orderID生成,后台还没搭建的情况
- cURL方式,按照提示对Note: Encode CLIENT_ID:CLIENT_SECRET in Base64 before sending it in the API call.进行Base64 Encode,一直都是提示404
- Postman的方式可以正确获得token
{
"scope": "https://uri.paypal.com/services/payments/futurepayments",
"access_token": "A21AAJ09kg1kH6oObs6FS1zTHLg3F-scr8dPDM8Cx7upLHpXvgQUltDbG-_8Lg4UoPXIFCuKGu0Ac0sq4XkHqJzJT0Gc2-lbQ",
"token_type": "Bearer",
"app_id": "APP-80W284485P519543T",
"expires_in": 32246,
"nonce": "2024-04-30T06:03:15ZYvWdeI2c-t4b1J0bbIGA3qHPCmZkWyPNvl7JoVpGN4o"
}
- 把步骤一获取的授权码替换如下,并在终端中执行
curl --location --request POST 'https://api-m.sandbox.paypal.com/v2/checkout/orders/' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer A21AAKY8fUjjesNQpycLWrkz9lITZoAF6bUaYRZ-JEG1Nbj0F6fiyxI1CtwurwhCt1Uezl5vL2_1VXmz9pkFwQfZwZN-7alVQ' \
--data-raw '{
"application_context": {
"shipping_preference": "NO_SHIPPING",
"user_action": "PAY_NOW"
},
"intent": "AUTHORIZE",
"purchase_units": [
{
"shipping": {
"address": {
"admin_area_2": "ShenZhen City",
"country_code": "CN",
"address_line_2": "Apt 9",
"address_line_1": "LongHuaQu LongHuaJieDaoBan",
"admin_area_1": "SZ",
"postal_code": "1111"
},
"name": {
"full_name": "Cook"
}
},
"payee": {
"merchant_id": "X5XAHHCG636FA",
"email_address": "merchant@email.com"
},
"amount": {
"currency_code": "USD",
"value": "5.00"
}
}
]
}'
应答如下,0GW60266PC254253L即是我们需要的订单号,这样就是可以愉快的发起支付请求了
{
"id": "0GW60266PC254253L",
"status": "CREATED",
"links": [{
"href": "https://api.sandbox.paypal.com/v2/checkout/orders/0GW60266PC254253L",
"rel": "self",
"method": "GET"
}, {
"href": "https://www.sandbox.paypal.com/checkoutnow?token=0GW60266PC254253L",
"rel": "approve",
"method": "GET"
}, {
"href": "https://api.sandbox.paypal.com/v2/checkout/orders/0GW60266PC254253L",
"rel": "update",
"method": "PATCH"
}, {
"href": "https://api.sandbox.paypal.com/v2/checkout/orders/0GW60266PC254253L/capture",
"rel": "capture",
"method": "POST"
}]
}
总结
1. 发起支付动作,文档上的示例
let payPalNativeClient = PayPalNativeCheckoutClient(config: config)
我是这么写的,运行时直接报异常
@objc func payPalButtonTapped() async {
let orderID = "0H807318BJ781474U"
let request = PayPalNativeCheckoutRequest(orderID: orderID)
await self.payPalClient.start(request: request)
}
看了官方Demo的写法,修改成如下
@objc func payPalButtonTapped() {
Task {
let orderID = "0H807318BJ781474U"
let request = PayPalNativeCheckoutRequest(orderID: orderID)
await self.payPalClient.start(request: request)
}
}