【问题标题】:Transaction not reflecting on the Paypal App Account交易未反映在 Paypal 应用程序帐户上
【发布时间】: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&currency=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&currency=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}!`));

【问题讨论】:

    标签: node.js paypal


    【解决方案1】:

    您是 PayPal 合作伙伴吗?直播环境需要用到这个:https://developer.paypal.com/docs/platforms/test-go-live/#2-go-live

    如果您愿意,PayPal 将指导您在沙盒和实时模式下进行测试。

    如果你不是,你无论如何都不能使用它。

    【讨论】:

    • 如您所见,我只是在沙盒上测试它。 var PAYPAL_API = "https://api-m.sandbox.paypal.com";还是这样吗?
    猜你喜欢
    • 2016-05-30
    • 1970-01-01
    • 2013-06-10
    • 1970-01-01
    • 2010-12-17
    • 2017-02-23
    • 2018-04-29
    • 2014-04-02
    • 2020-09-19
    相关资源
    最近更新 更多