【发布时间】:2021-06-26 04:26:24
【问题描述】:
我在我的平台上成功创建了Platform Transaction。除平台费用外,所有转账均按预期进行。它们反映在商家卖方和买方方面,但不反映在平台帐户上。
交易详情快照
-$9.33 USD的合作伙伴佣金不会显示在平台帐户上。事实上,这笔交易并没有以任何方式反映。从 Paypal Sandbox 应用程序帐户中根本无法判断它是否发生过。
我错过了什么?
提前谢谢大家。
客户端:index.html
<html>
<head>
<meta charset="utf-8"/>
<!-- Optimal rendering on mobile devices. -->
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Optimal Internet Explorer compatibility -->
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<!-- Sample CSS styles for demo purposes. You can override these styles to match your web page's branding. -->
<link rel="stylesheet" type="text/css" href="https://www.paypalobjects.com/webstatic/en_US/developer/docs/css/cardfields.css"/>
<!-- JavaScript SDK -->
<script src="https://www.paypal.com/sdk/js?components=buttons,hosted-fields&client-id=Ae4XWCzGDY24rKpazdCnRnT1wUjnQ_2PzLF5aOhviaUfQ7_O34rr8NqrunXe7PxCi-sEt7noZfr1ojbs" data-client-token="eyJicmFpbnRyZWUiOnsiYXV0aG9yaXphdGlvbkZpbmdlcnByaW50IjoiZWNkYWE1MzZjNjQ5Nzg1YjU2ZWQ5NGMyZGU2ZjRjMGQzY2FiMDY0MzkyNTA3YTkxZTU2MjI3MDlhZTMzOWUyNHxtZXJjaGFudF9pZD1yd3dua3FnMnhnNTZobTJuJnB1YmxpY19rZXk9NjNrdm4zN3Z0MjlxYjRkZiZjcmVhdGVkX2F0PTIwMjEtMDMtMjlUMTM6Mjg6MTMuOTQxWiIsInZlcnNpb24iOiIzLXBheXBhbCJ9LCJwYXlwYWwiOnsiaWRUb2tlbiI6ImV5SnJhV1FpT2lJNVpqWmxOalV5T0RGallXWmhORFU1WkRReU9EWmhPRE5pWVdZMVl6aGtPRFUwWVdNNE5XRmtJaXdpZEhsd0lqb2lTbGRVSWl3aVlXeG5Jam9pVWxNeU5UWWlmUS5leUpwYzNNaU9pSm9kSFJ3Y3pvdkwyRndhUzV6WVc1a1ltOTRMbkJoZVhCaGJDNWpiMjBpTENKemRXSWlPaUpvZEhSd2N6b3ZMM2QzZHk1d1lYbHdZV3d1WTI5dEwzZGxZbUZ3Y0hNdllYVjBhQzlwWkdWdWRHbDBlUzkxYzJWeUwwSlhRazEyZVhoclJsWjBkWHBCZUd4RmNGZENiMVJRTkhSNGFHOVRVMnh0YVZWWmNtbDZhM3BrWkdjaUxDSmhZM0lpT2xzaVkyeHBaVzUwSWwwc0ltRjFaQ0k2SWtGbE5GaFhRM3BIUkZreU5ISkxjR0Y2WkVOdVVtNVVNWGRWYW01Ulh6SlFla3hHTldGUGFIWnBZVlZtVVRkZlR6TTBjbkk0VG5GeWRXNVlaVGRRZUVOcExYTkZkRGR1YjFwbWNqRnZhbUp6SWl3aVlYVjBhRjkwYVcxbElqb3hOakUzTURJME5EazBMQ0poYlhJaU9sdGRMQ0poZWlJNkluTmlMbk5zWXlJc0ltVjRjQ0k2TVRZeE56QXlOVE01TkN3aWMyVnpjMmx2Ymw5cGJtUmxlQ0k2SWxoMVNuUnBiMDU0WWs1YU1HOVFUVzVpTWtkNVpXdHRRMWh3UXlJc0ltbGhkQ0k2TVRZeE56QXlORFE1TkN3aWFuUnBJam9pVlRKQlFVbGtiVVZETTJjekxVTkpOelpDYWtSdk56WjNUVFpoZDJ4VWJuWmFNMGhsVW5kWmNXRmxTazUyZW1SWFpWTmlhMUUyVERoUU5qbFdUako0Y21kR1prTkNUVGxHYVdGRGNVNHhSUzFqTVZobVEzSndZWFJPTWxGWVltczFZbE4yVlZveVpYTlRTRzU1VG1aaWRWUkxZamxQUjB0cWNGRjZSbWR5V0ZFaUxDSmpiR2xsYm5SZmFXUWlPaUpCWlRSWVYwTjZSMFJaTWpSeVMzQmhlbVJEYmxKdVZERjNWV3B1VVY4eVVIcE1SalZoVDJoMmFXRlZabEUzWDA4ek5ISnlPRTV4Y25WdVdHVTNVSGhEYVMxelJYUTNibTlhWm5JeGIycGljeUo5LkhObzlndU5SQVktSDZTR2tUR0xxRUFtbDNWRkJwNHRwNjdSSVJPN1NMbm5PRUtkWGFHSjhfYkJfR3N5dWxZeGQ4Slhnd3duTWV4ejZYaElEUnVtVzVkaDloQm9CbFctTGtNUEZ6cmVDZnk3SnVnbmZPYk9PaWRhV19Wd1IyRXpLSTZ1UzZWaFhKbEFvaWI1U3dfYjNXYlVHR2tudUM5cjZDZ0xlWnNTaDVQZDRuaFc1M0pplatformlHQTZkOVc3ZU5VZXBKNUJwd1FJWkRVYmJyY2JXelFDMzRFN0tQbndjOENIQWh3UGNSZWpWaktWWVlLSE9lUF9KeWpEbFZDWXM4NU5YVEExYV9ldDdFUHZmcmN1NzF0S3FhR0hNV21XWE9KS245UGZ2Zk10b2ZfRWN3SmhVd2RBU1ZqZmU4VjlzM3ZidzRJRGZHMFRjYzY1d2hIaFp4Sl94dyIsImFjY2Vzc1Rva2VuIjoiQTIxQUFJNTNiLVl0Qk1neFlmb1NQZHJKUUsxZTBCYVZSZm01X3BPNlg4bnktZ292S1l3dy11YU1fWm8wM0YxQXdzenZfYjF4RmZJTkE1YkNfUEZya3A0bkxxMzljdWdndyJ9fQ=="></script>
<!-- Include the PayPal JavaScript SDK -->
<script src="https://www.paypal.com/sdk/js?client-id=Ae4XWCzGDY24rKpazdCnRnT1wUjnQ_2PzLF5aOhviaUfQ7_O34rr8NqrunXe7PxCi-sEt7noZfr1ojbs¤cy=USD" data-namespace="paypal_sdk"></script>
</head>
<body>
<!-- JavaScript SDK -->
<script src="https://www.paypal.com/sdk/js?components=hosted-fields&client-id=Ae4XWCzGDY24rKpazdCnRnT1wUjnQ_2PzLF5aOhviaUfQ7_O34rr8NqrunXe7PxCi-sEt7noZfr1ojbs&merchant-id=H82BJAGD75E6C¤cy=USD&intent=capture" data-partner-attribution-id="FLAVORsb-z1ivv5077605_MP" data-client-token="eyJicmFpbnRyZWUiOnsiYXV0aG9yaXphdGlvbkZpbmdlcnByaW50IjoiZWNkYWE1MzZjNjQ5Nzg1YjU2ZWQ5NGMyZGU2ZjRjMGQzY2FiMDY0MzkyNTA3YTkxZTU2MjI3MDlhZTMzOWUyNHxtZXJjaGFudF9pZD1yd3dua3FnMnhnNTZobTJuJnB1YmxpY19rZXk9NjNrdm4zN3Z0MjlxYjRkZiZjcmVhdGVkX2F0PTIwMjEtMDMtMjlUMTM6Mjg6MTMuOTQxWiIsInZlcnNpb24iOiIzLXBheXBhbCJ9LCJwYXlwYWwiOnsiaWRUb2tlbiI6ImV5SnJhV1FpT2lJNVpqWmxOalV5T0RGallXWmhORFU1WkRReU9EWmhPRE5pWVdZMVl6aGtPRFUwWVdNNE5XRmtJaXdpZEhsd0lqb2lTbGRVSWl3aVlXeG5Jam9pVWxNeU5UWWlmUS5leUpwYzNNaU9pSm9kSFJ3Y3pvdkwyRndhUzV6WVc1a1ltOTRMbkJoZVhCaGJDNWpiMjBpTENKemRXSWlPaUpvZEhSd2N6b3ZMM2QzZHk1d1lYbHdZV3d1WTI5dEwzZGxZbUZ3Y0hNdllYVjBhQzlwWkdWdWRHbDBlUzkxYzJWeUwwSlhRazEyZVhoclJsWjBkWHBCZUd4RmNGZENiMVJRTkhSNGFHOVRVMnh0YVZWWmNtbDZhM3BrWkdjaUxDSmhZM0lpT2xzaVkyeHBaVzUwSWwwc0ltRjFaQ0k2SWtGbE5GaFhRM3BIUkZreU5ISkxjR0Y2WkVOdVVtNVVNWGRWYW01Ulh6SlFla3hHTldGUGFIWnBZVlZtVVRkZlR6TTBjbkk0VG5GeWRXNVlaVGRRZUVOcExYTkZkRGR1YjFwbWNqRnZhbUp6SWl3aVlYVjBhRjkwYVcxbElqb3hOakUzTURJME5EazBMQ0poYlhJaU9sdGRMQ0poZWlJNkluTmlMbk5zWXlJc0ltVjRjQ0k2TVRZeE56QXlOVE01TkN3aWMyVnpjMmx2Ymw5cGJtUmxlQ0k2SWxoMVNuUnBiMDU0WWs1YU1HOVFUVzVpTWtkNVpXdHRRMWh3UXlJc0ltbGhkQ0k2TVRZeE56QXlORFE1TkN3aWFuUnBJam9pVlRKQlFVbGtiVVZETTJjekxVTkpOelpDYWtSdk56WjNUVFpoZDJ4VWJuWmFNMGhsVW5kWmNXRmxTazUyZW1SWFpWTmlhMUUyVERoUU5qbFdUako0Y21kR1prTkNUVGxHYVdGRGNVNHhSUzFqTVZobVEzSndZWFJPTWxGWVltczFZbE4yVlZveVpYTlRTRzU1VG1aaWRWUkxZamxQUjB0cWNGRjZSbWR5V0ZFaUxDSmpiR2xsYm5SZmFXUWlPaUpCWlRSWVYwTjZSMFJaTWpSeVMzQmhlbVJEYmxKdVZERjNWV3B1VVY4eVVIcE1SalZoVDJoMmFXRlZabEUzWDA4ek5ISnlPRTV4Y25WdVdHVTNVSGhEYVMxelJYUTNibTlhWm5JeGIycGljeUo5LkhObzlndU5SQVktSDZTR2tUR0xxRUFtbDNWRkJwNHRwNjdSSVJPN1NMbm5PRUtkWGFHSjhfYkJfR3N5dWxZeGQ4Slhnd3duTWV4ejZYaElEUnVtVzVkaDloQm9CbFctTGtNUEZ6cmVDZnk3SnVnbmZPYk9PaWRhV19Wd1IyRXpLSTZ1UzZWaFhKbEFvaWI1U3dfYjNXYlVHR2tudUM5cjZDZ0xlWnNTaDVQZDRuaFc1M0pplatformlHQTZkOVc3ZU5VZXBKNUJwd1FJWkRVYmJyY2JXelFDMzRFN0tQbndjOENIQWh3UGNSZWpWaktWWVlLSE9lUF9KeWpEbFZDWXM4NU5YVEExYV9ldDdFUHZmcmN1NzF0S3FhR0hNV21XWE9KS245UGZ2Zk10b2ZfRWN3SmhVd2RBU1ZqZmU4VjlzM3ZidzRJRGZHMFRjYzY1d2hIaFp4Sl94dyIsImFjY2Vzc1Rva2VuIjoiQTIxQUFJNTNiLVl0Qk1neFlmb1NQZHJKUUsxZTBCYVZSZm01X3BPNlg4bnktZ292S1l3dy11YU1fWm8wM0YxQXdzenZfYjF4RmZJTkE1YkNfUEZya3A0bkxxMzljdWdndyJ9fQ=="></script>
<!-- Buttons container -->
<div id="paypal-button-container"></div>
<!-- Implementation -->
<script>
let orderId;
// Displays PayPal buttons
paypal_sdk.Buttons({
style: {
layout: 'horizontal'
},
// Call your server to set up the transaction
createOrder: function(data, actions) {
return fetch('/demo/checkout/api/paypal/platform_store_order/create/', {
method: 'post'
}).catch(error => {
console.error('ERR -> fetch : ' + error.message);
}).then(function(res) {
return res.json();
}).catch(error => {
console.error('ERR -> res : ' + error.message);
}).then(function(orderData) {
return orderData.id;
}).catch(error => {
console.error('ERR -> orderData : ' + error.message);
});
},
// Call your server to finalize the transaction
onApprove: function(data, actions) {
return fetch('/demo/checkout/api/paypal/order_platform_store/', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({'orderID': data.orderID, 'payerID': data.payerID})
}).then(function(res) {
return res.json();
}).then(function(orderData) {
// Three cases to handle:
// (1) Recoverable INSTRUMENT_DECLINED -> call actions.restart()
// (2) Other non-recoverable errors -> Show a failure message
// (3) Successful transaction -> Show confirmation or thank you
// This example reads a v2/checkout/orders capture response, propagated from the server
// You could use a different API or structure for your 'orderData'
var errorDetail = Array.isArray(orderData.details) && orderData.details[0];
if (errorDetail && errorDetail.issue === 'INSTRUMENT_DECLINED') {
return actions.restart(); // Recoverable state, per:
// https://developer.paypal.com/docs/checkout/integration-features/funding-failure/
}
if (errorDetail) {
var msg = 'Sorry, your transaction could not be processed.';
if (errorDetail.description) {
msg += '\n\n' + errorDetail.description;
}
if (orderData.debug_id){
msg += ' (' + orderData.debug_id + ')'
};
return alert(msg); // Show a failure message
}
// Show a success message
alert('Transaction : ' + JSON.stringify(orderData));
});
}
}).render("#paypal-button-container");
</script>
</body>
</html>
NODE app.js
const path = require("path");
var express = require("express");
var cors = require("cors");
var app = express();
var request = require("request");
const port = process.env.PORT || 3000;
app.use(cors());
var bodyParser = require("body-parser");
app.use(
bodyParser.urlencoded({
extended: true,
})
);
app.use(bodyParser.json());
// Add your credentials:
// Add your client ID and secret
var CLIENT = "Ae4XWCzGDY24rKpazdCnRnT1wUjnQ_2PzLF5aOhviaUfQ7_O34rr8NqrunXe7PxCi-sEt7noZfr1ojbs";
var SECRET = "EMmNF1LZSOooLUAxEt5csF-rMyIseuV5D6qOoKMzbyUEDaQEhO_DjLarbVsF_vLiXnGHi8qFL13gebg_";
var PAYPAL_API = "https://api-m.sandbox.paypal.com";
const paypal = require("@paypal/checkout-server-sdk");
let environment = new paypal.core.SandboxEnvironment(CLIENT, SECRET);
let client = new paypal.core.PayPalHttpClient(environment);
app.get("/", function (req, res) {
res.sendFile(path.join(__dirname + "/index.html"));
});
// Set up the payment:
// 1. Set up a URL to handle requests from the PayPal button
app.post("/demo/checkout/api/paypal/order/create/", async function (req, res) {
let ordersCreateRequest = new paypal.orders.OrdersCreateRequest();
ordersCreateRequest.requestBody({
"intent": "CAPTURE",
"purchase_units": [
{
"amount": {
"currency_code": "USD",
"value": "9.88",
},
},
],
});
// Call API with your client and get a response for your call
let createOrder = async function () {
let response = await client.execute(ordersCreateRequest);
return response;
};
let platformOrder = await createOrder();
let orderId = platformOrder.result.id;
// 2. Call /v2/checkout/orders to set up the Order
res.json({
id: orderId,
});
});
// Set up the payment:
// 1. Set up a URL to handle requests from the PayPal button
app.post("/demo/checkout/api/paypal/platform_store_order/create/", async function (req, res) {
let ordersCreateRequest = new paypal.orders.OrdersCreateRequest();
ordersCreateRequest.requestBody({
"intent": "CAPTURE",
"purchase_units": [
{
"amount": {
"currency_code": "USD",
"value": "31.13",
},
"payee": {
"email_address": "platform@business.example.com",
},
"payment_instruction": {
"disbursement_mode": "INSTANT",
"platform_fees": [
{
"amount": {
"currency_code": "USD",
"value": "9.33",
},
},
],
},
},
],
});
// Call API with your client and get a response for your call
let createOrder = async function () {
let response = await client.execute(ordersCreateRequest);
return response;
};
let platformOrder = await createOrder();
let orderId = platformOrder.result.id;
res.json({
id: orderId,
});
});
// 1. Set up a URL to handle requests from the PayPal button.
app.post("/demo/checkout/api/paypal/order_platform_store/", async function (req, res) {
// 2. Get the payment ID and the payer ID from the request query.
var orderID = req.body.orderID;
request.post(
PAYPAL_API + "/v2/checkout/orders/" + orderID + "/capture",
{
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer A21AAJ8sH_Uq73w8XonQYB9rc1STsZpoK_Q14PkHbRgxtbYUN6FvCg-FbOKYIDlt0Zzo8xVQMvSuCAaRgjSfGoEPYRbxk62xQ",
"PayPal-Partner-Attribution-Id": "FLAVORsb-z1ivv5077605_MP",
},
},
function (err, response, body) {
if (err) {
console.error(err);
return res.sendStatus(500);
}
res.json(response);
}
);
});
app.listen(port, () => console.log(`Listening on port ${port}!`));
【问题讨论】: