PayPal快速结账:无法使用沙盒测试帐户处理付款

时间:2017-07-09 13:36:51

标签: paypal express-checkout

我尝试将PayPal Express Checkout集成到我的webapp(服务器端REST)中,我设法: get create-payment working

但是,当我尝试使用沙盒测试买家帐户登录时,failed to process the payment.

POST请求出现400 Bad请求错误:

POST https://www.sandbox.paypal.com/webapps/hermes/api/batch/setbuyer 400 (Bad Request)

以下回复:

{
"ack": "success",
"data": {
    "buyerEligibility": {
        "ack": "success",
        "data": {
            "eligible": true,
            "clearedRT": false
        },
        "meta": {
            "calc": "8f7cc8e266c07",
            "rlog": "PVs6nBwuIQ9X2gSdIEqzR%2BxkmohYC3WlOiW4HauQ%2FY%2Fh%2BkWFfmr2pOeyxVs3sSiqXDydWuJ%2B6QWLAsZZVtRfIA_15d276b99bf"
        },
        "server": "xG7Ol-1A5r4xEqHEubzBtkj6LgLo88Z7UFOPmqsoK957Q11gkENbvzjGa02RjhyhvYG_ff2SZRFgHYp0Nq5rCCIdwQAwbwL-RkZ0piofvsP6-i9NmpkouuuH47EBynDbMencyfNKhT-cIewGtGK2jKUX_q0FaWq9Gx0MaRB6QBwINBmRQB5tAuklfWE8ooIwOO7szgPXVg9pOXWI2ukxup08j93HODToZ4DnSLuqCK6XM2M49-_DDSyS6GviI3gWrBy7BLOsHky"
    },
    "eConsent": {
        "ack": "success",
        "data": {
            "required": false
        },
        "meta": {
            "calc": "8f7cc8e266c07",
            "rlog": "PVs6nBwuIQ9X2gSdIEqzR%2BxkmohYC3WlOiW4HauQ%2FY%2Fh%2BkWFfmr2pOeyxVs3sSiqXDydWuJ%2B6QWLAsZZVtRfIA_15d276b99bf"
        },
        "server": "-bDk6FVAJFycsTL-R5q_CGdrJwDz9XbAF9KqMHpr6QIMACZ6IA5zQ_BVyqi3jy6w9pKC5SS4TBrpDB_OJC0rU1W5wz5XBgo3ze_iOG0gDEwxuzu7WtAT1Nv5_VmLhmUWIdMm7qtgfy1y11v18zXSxhATUDaRI8hNdlnArSlBtKVNGWkhCD4OTp4KvSBXQ3lLHm-wCSrJzhpEmBoNZmDQMrd4wv1YEYA0VFPG1cPHapq9t4xJMLfiZOad10irqxJP"
    },
    "createCheckoutSession": {
        "ack": "contingency",
        "contingency": "PAYER_CANNOT_PAY",
        "errorData": {
            "cause": "",
            "step_up_context": {}
        },
        "meta": {
            "calc": "8f7cc8e266c07",
            "rlog": "PVs6nBwuIQ9X2gSdIEqzR%2BxkmohYC3WlOiW4HauQ%2FY%2Fh%2BkWFfmr2pOeyxVs3sSiqXDydWuJ%2B6QWLAsZZVtRfIA_15d276b99bf"
        },
        "server": "-eKOVjOLP5i0k_9Et8_N5HyfLSVBzycsA2AE8UY8RD88MnM3729QBQoHY2eD3sMhSThBqdYmvFoARIAbkHNoOT9jsHzAUCk1CtbA717xHK5gSuYujf5mvuDJQFXWlPEDBk7XFlZSyhUWy8VGKvYWwWhuTSzcjMdKIzRI_XTjfA2hQpzIvkbRQ5jLMDIIKeNm1XrF3mEMN3gkHzZIc2OBiRaVEA2Q0se_uVgEEGIbSgN2aeSOeh4WiMC08zUCvmdCLyCP0ZyE24fzDvL4ZMUurG"
    }
},
"meta": {
    "calc": "8f7cc8e266c07",
    "rlog": "PVs6nBwuIQ9X2gSdIEqzR%2BxkmohYC3WlOiW4HauQ%2FY%2Fh%2BkWFfmr2pOeyxVs3sSiqXDydWuJ%2B6QWLAsZZVtRfIA_15d276b99bf"
},
"server": "JwJRYq2SF3kUujC16-VsiMQu8IDN_RxPNOz8wY8m8YD4P3PzhHZB73hNd_IM9PktfJcPPHx2RyVUk1PV8bC2lLtejwTFKzq-7QDM9nLmxJLw7os2tgLnGYAebFJAkmIt2fFvlncVMrAg9bAsMF9INhPqixaCEWn7ug9OcPCci_3autJi3cvmTLb_8XvTaGBpPxI0ASQnkXTSVJa2GPIptYhGVHFN5N92hFdxzwp2uYQhHeJrePmExV4NlLd0s_wa"

}

PayPal Express Checkout的客户端实施:

class PayPalButton extends Component {
render() {
    const Btn = paypal.Button.driver('react', {React, ReactDOM});
    const CREATE_PAYMENT_URL = `${ROOT_URL}/paypal/create-payment/${this.props.regId}`;
    const EXECUTE_PAYMENT_URL = `${ROOT_URL}/paypal/execute-payment/${this.props.regId}`;
    const token = localStorage.getItem('deotoken');

    let client = {
        sandbox: 'TO_BE_REPLACED_WITH_SANDBOX_CLIENT_ID'
    };

    let payment = () => {
  return paypal.request({
    method: 'post',
    url: CREATE_PAYMENT_URL,
    headers: {
        authorization: token
    }
  })
  .then(function(data) {
      return data.id;
  });
    };

    let onAuthorize = (data) => {
  return paypal.request({
    method: 'post',
    url: EXECUTE_PAYMENT_URL,
    headers: {
        authorization: token
    },
    json: {
                paymentID: data.paymentID,
      payerID:   data.payerID
    } 
  }).then(function() {
      // The payment is complete!
      // You can now show a confirmation message to the customer
      console.log('done');
  });
    };

return (
    <div>
    <Btn env={'sandbox'}
      client={client}
      payment={payment}
      commit={true}
      onAuthorize={onAuthorize}
    />
    </div>
);
}

我的服务器端实现):

module.exports = {
createPayment(req, res, next) {
    const { registration_id } = req.params;
    const { user } = req;

    Registration.findById(registration_id)
    .populate({ path: 'category', model: 'category' })
    .populate({ path: 'orders.meal', model: 'meal' })
    .then(reg => {
        if (reg) {
            const categoryItem = [{
                name: reg.category.name,
                sku: reg.category.name,
                price: reg.category.price,
                currency: 'MYR',
                quantity: 1
            }];
            const ordersItems = reg.orders.map(order => {
                return {
                    name: order.meal.name,
                    sku: order.meal.name,
                    price: order.meal.price,
                    currency: 'MYR',
                    quantity: order.quantity
                }
            });

            const create_payment_json = {
                intent: 'sale',
                payer: {
                    payment_method: 'paypal'
                },
                redirect_urls: {
                    return_url: 'http://localhost:8080/',
                    cancel_url: 'http://localhost:8080/'
                },
                transactions: [{
                    item_list: {
                        items: [...categoryItem, ...ordersItems]
                    },
                    amount: {
                        currency: 'MYR',
                        total: reg.totalBill
                    }
                }]
            };

            paypal.payment.create(create_payment_json, function(err, payment) {
                if (err) { 
                    next(err); 
                } else {
                    res.send(payment);
                }

            })
        } else {
            return res.status(422).send({error: 'Registration not found'});
        }
    })
    .catch(next);

},
executePayment(req, res, next) {
    const { registration_id } = req.params;
    const { paymentID, payerID } = req.body;

    const execute_payment_json = {
        payer_id: payerID
    }

    paypal.payment.execute(paymentID, execute_payment_json, function(err, paypalResponse) {
        if (err) {
            next(err);
        } else {
            if (paypalResponse.state === 'approved') {
                const payment = new Payment({
                    user: req.user._id,
                    registration: registration_id,
                    amount: paypalResponse.transactions[0].amount.total,
                    currency: paypalResponse.transactions[0].amount.currency,
                    paypalPaymentId: paypalResponse.id
                });

                payment.save()
                    .then(p => res.send(p))
                    .catch(next);
            } else {
                res.status(422).send({ error: 'Payment not approved' });
            }
        }
    });
}

};

问题是什么?我怎样才能做到这一点?

1 个答案:

答案 0 :(得分:1)

我遇到了同样的问题。 我已经在Paypal沙箱中将INR设置为我的货币,但是通过API调用将金额发送为USD。 因此,我认为我们必须使用在沙箱中设置的货币进行交易。

先前有效载荷:

function change_slug_struct( $query ) {

    if ( ! $query->is_main_query() || 2 != count( $query->query ) || ! isset( $query->query['page'] ) ) {
        return;
    }

    if ( ! empty( $query->query['name'] ) ) {
        $query->set( 'post_type', array( 'post', 'single-link', 'page' ) );
    } elseif ( ! empty( $query->query['pagename'] ) && false === strpos( $query->query['pagename'], '/' ) ) {
        $query->set( 'post_type', array( 'post', 'single-link', 'page' ) );

        // We also need to set the name query var since redirect_guess_404_permalink() relies on it.
        $query->set( 'name', $query->query['pagename'] );
    }
}
add_action( 'pre_get_posts', 'change_slug_struct' );

更改有效负载后:

transactions: [{
                item_list: {
                    items: [...categoryItem, ...ordersItems]
                },
                amount: {
                    currency: 'USD',
                    total: reg.totalBill
                }
            }]

更改货币后,我的代码可以正常运行!