paypal官方文档
一、PayPal的api文档:
https://developer.paypal.com/dashboard/
https://developer.paypal.com/docs/integration/direct/payments/paypal-payments/#search-payment-details
常用结账方式
PayPal配置密钥
配置webhook
Sandbox Webhooks
分别对应:事件回调地址 webhooks的id 触发事件类型
PayPal
- 开发者账号
https://developer.paypal.com/developer/accounts?event=createSuccess - 查找商户账户密码
- 再登陆https://www.sandbox.paypal.com/mep/dashboard
- 在浏览器输入:https://www.sandbox.paypal.com/,点击登录,输入创建好的 ”商家账号“ 的邮箱和密码
API流程
Integration steps 集成步骤
- Required 必填 Set up your development environment
.
设置开发环境。 - Required 必填 Create PayPal payment
. 创建PayPal付款。 - Required 必填 Get payment approval
. 获得付款批准。 - Required 必填 Execute payment
. 执行付款。 - Optional 自选 Search payment details
. 搜索付款详细信息。
Create PayPal payment 创建PayPal付款
After you collect the payment details from the customer, specify the payment details in a /payment call.
从客户收集付款详细信息后,在 /payment 呼叫中指定付款详细信息。
In the request URI, set the .
在请求 URI 中,设置 .
In the JSON request body, set the intent to sale, the redirect URLs, the payment_method to paypal, and the transaction information in the transactions array, which contains one or more transaction objects:
在 JSON 请求正文中,在 transactions 包含一个或多个 transaction 对象的数组中设置 to、重定向 URL、 intent payment_method to paypal sale 和事务信息:
curl -v -X POST https://api-m.sandbox.paypal.com/v1/payments/payment \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <Access-Token>" \
-d '{
"intent": "sale",
"payer": {
"payment_method": "paypal"
},
"transactions": [{
"amount": {
"total": "30.11",
"currency": "USD",
"details": {
"subtotal": "30.00",
"tax": "0.07",
"shipping": "0.03",
"handling_fee": "1.00",
"shipping_discount": "-1.00",
"insurance": "0.01"
}
},
"description": "This is the payment transaction description.",
"custom": "EBAY_EMS_90048630024435",
"invoice_number": "48787589673",
"payment_options": {
"allowed_payment_method": "INSTANT_FUNDING_SOURCE"
},
"soft_descriptor": "ECHI5786786",
"item_list": {
"items": [{
"name": "hat",
"description": "Brown color hat",
"quantity": "5",
"price": "3",
"tax": "0.01",
"sku": "1",
"currency": "USD"
}, {
"name": "handbag",
"description": "Black color hand bag",
"quantity": "1",
"price": "15",
"tax": "0.02",
"sku": "product34",
"currency": "USD"
}],
"shipping_address": {
"recipient_name": "Hello World",
"line1": "4thFloor",
"line2": "unit#34",
"city": "SAn Jose",
"country_code": "US",
"postal_code": "95131",
"phone": "011862212345678",
"state": "CA"
}
}
}],
"note_to_payer": "Contact us for any questions on your order.",
"redirect_urls": {
"return_url": "https://example.com",
"cancel_url": "https://example.com"
}
}'
A successful call returns confirmation of the transaction, with the created state and a payment ID that you can use in subsequent calls:
Execute payment 支付执行完
To execute the payment after the customer’s approval, make a /payment/execute/ call. In the JSON request body, use the payerID value that was passed to your site. In the header, use the access token that you used when you created the payment.
curl -v -X POST https://api-m.sandbox.paypal.com/v1/payments/payment/PAY-34629814WL663112AKEE3AWQ/execute \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <Access-Token>" \
-d '{
"payer_id": "RRCYJUTFJGZTA"
}'
The execute payment call returns a paymentobject with transaction details:
{
"id": "PAY-4N746561P0587231SKQQK6MY",
"create_time": "2014-09-22T23:22:27Z",
"update_time": "2014-09-22T23:31:13Z",
"state": "approved",
"intent": "sale",
"payer": {
"payment_method": "paypal",
"payer_info": {
"email": "npurayil-uspr-60@paypal.com",
"first_name": "Brian",
"last_name": "Robinson",
"payer_id": "JMKDKJ4D7DG7G",
"shipping_address": {
"line1": "4thFloor",
"line2": "unit#34",
"city": "SAn Jose",
"state": "CA",
"postal_code": "95131",
"country_code": "US",
"phone": "011862212345678",
"recipient_name": "HelloWorld"
}
}
},
"transactions": [
{
"amount": {
"total": "30.11",
"currency": "USD",
"details": {
"subtotal": "30.00",
"tax": "0.07",
"shipping": "0.03",
"handling_fee": "1.00",
"insurance": "0.01",
"shipping_discount": "-1.00"
}
},
"description": "This is the payment transaction description.",
"item_list": {
"items": [
{
"name": "hat",
"sku": "1",
"price": "3.00",
"currency": "USD",
"quantity": "5",
"description": "Brown color hat",
"tax": "0.01"
},
{
"name": "handbag",
"sku": "product34",
"price": "15.00",
"currency": "USD",
"quantity": "1",
"description": "Black color handbag",
"tax": "0.02"
}
],
"shipping_address": {
"recipient_name": "HelloWorld",
"line1": "4thFloor",
"line2": "unit#34",
"city": "SAn Jose",
"state": "CA",
"phone": "011862212345678",
"postal_code": "95131",
"country_code": "US"
}
},
"related_resources": [
{
"sale": {
"id": "4XP56210M0797192Y",
"create_time": "2014-09-22T23:22:27Z",
"update_time": "2014-09-22T23:31:13Z",
"amount": {
"total": "30.11",
"currency": "USD"
},
"payment_mode": "INSTANT_TRANSFER",
"state": "completed",
"protection_eligibility": "ELIGIBLE",
"protection_eligibility_type": "ITEM_NOT_RECEIVED_ELIGIBLE",
"transaction_fee": {
"value": "1.75",
"currency": "USD"
},
"parent_payment": "PAY-4N746561P0587231SKQQK6MY",
"links": [
{
"href": "https://api-m.paypal.com/v1/payments/sale/4XP56210M0797192Y",
"rel": "self",
"method": "GET"
},
{
"href": "https://api-m.paypal.com/v1/payments/sale/4XP56210M0797192Y/refund",
"rel": "refund",
"method": "POST"
},
{
"href": "https://api-m.paypal.com/v1/payments/payment/PAY-4N746561P0587231SKQQK6MY",
"rel": "parent_payment",
"method": "GET"
}
]
}
}
]
}
],
"links": [
{
"href": "https://api-m.paypal.com/v1/payments/payment/PAY-4N746561P0587231SKQQK6MY",
"rel": "self",
"method": "GET"
}
]
}
refund 退款
curl -v https://api-m.sandbox.paypal.com/v1/payments/sale/67D22837NN7279935/refund \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <Access-Token>" \
-d '{}'
二、实战代码
标准结账支付
yaml配置
paypal配置
paypal.mode=sandbox/live
paypal.client.app = xxx
paypal.client.secret = xxxxxxxxxxxxxxxx
paypal.client.webhook_id =xxx
maven sdk引入
<dependency>
<groupId>com.paypal.sdk</groupId>
<artifactId>rest-api-sdk</artifactId>
<version>1.14.0</version>
<exclusions>
<exclusion>
<artifactId>gson</artifactId>
<groupId>com.google.code.gson</groupId>
</exclusion>
</exclusions>
</dependency>
Create PayPal payment 创建PayPal付款
/**
* 创建订单
*
* @param moneyBigDecimal
* @return
* @throws PayPalRESTException
*/
@Override
public Payment createPayment(BigDecimal moneyBigDecimal) throws PayPalRESTException {
log.info("订单金额:{}", moneyBigDecimal.doubleValue());
// 成功与失败回调地址
String cancelUrl = PAYPAL_CANCEL_URL.replace("{Redirect_Url}",redirectUrl).replace("{contextPath}", contextPath);
String successUrl = PAYPAL_SUCCESS_URL.replace("{Redirect_Url}",redirectUrl).replace("{contextPath}", contextPath);
Payment payment = this.createPayment(
moneyBigDecimal.doubleValue(),
"USD",
PayPalPaymentMethod.paypal,
PayPalPaymentIntent.sale,
"payment description",
cancelUrl,
successUrl);
if (ObjectUtils.isNotEmpty(payment)) {
log.info("Payment created successfully");
} else {
log.error("Payment Fail");
return null;
}
return payment;
}
@Resource
private APIContext apiContext;
/**
* 支付方法
*
* @param total 交易金额
* @param currency 货币类型
* @param method 枚举-作用
* @param intent 枚举-意图
* @param description 交易描述
* @param cancelUrl 交易取消后跳转url
* @param successUrl 交易成功后跳转url
* @return Payment
* @throws PayPalRESTException
*/
@Override
public Payment createPayment(
Double total,
String currency,
PayPalPaymentMethod method,
PayPalPaymentIntent intent,
String description,
String cancelUrl,
String successUrl) throws PayPalRESTException {
//设置金额和单位对象
Amount amount = new Amount();
amount.setCurrency(currency);
amount.setTotal(String.format("%.2f", total));
//设置具体的交易对象
Transaction transaction = new Transaction();
transaction.setDescription(description);
transaction.setAmount(amount);
//交易集合-可以添加多个交易对象
List<Transaction> transactions = new ArrayList<>();
transactions.add(transaction);
Payer payer = new Payer();
payer.setPaymentMethod(method.toString());
Payment payment = new Payment();
payment.setIntent(intent.toString());
payment.setPayer(payer);
payment.setTransactions(transactions);
//设置返回的url
RedirectUrls redirectUrls = new RedirectUrls();
redirectUrls.setCancelUrl(cancelUrl);
redirectUrls.setReturnUrl(successUrl);
//加入反馈对象
payment.setRedirectUrls(redirectUrls);
//加入认证并创建交易
return payment.create(apiContext);
}
支付完成回调
//获取PayPal支付信息 入参:paymentId
Payment payment = Payment.get(apiContext, paymentId);
String payerId;
if (payment.getPayer() != null) {
payerId = payment.getPayer().getPayerInfo().getPayerId();
log.info("payerId:{}", payerId);
//执行回调
Payment executePayment = this.executePayment(paymentId, payerId);
log.info("执行回调executePayment:{}", executePayment);
if (!org.springframework.util.ObjectUtils.isEmpty(executePayment)) {
log.info("Payment execute successfully");
log.info(executePayment.toJSON());
}
String saleId = null;
Sale sale = executePayment.getTransactions().get(0).getRelatedResources().get(0).getSale();
if (org.springframework.util.ObjectUtils.isEmpty(sale) && "completed".equals(sale.getState())) {
saleId = sale.getId();
}
/**
* 并执行交易(相当于提交事务)
*
* @param paymentId
* @param payerId
* @return
* @throws PayPalRESTException
*/
@Override
public Payment executePayment(String paymentId, String payerId) throws PayPalRESTException {
Payment payment = new Payment();
payment.setId(paymentId);
PaymentExecution paymentExecute = new PaymentExecution();
paymentExecute.setPayerId(payerId);
return payment.execute(apiContext, paymentExecute);
}
参考文档:
https://www.pianshen.com/article/3031768019/