skip to Main Content

I’m trying to implement PayPal payments on my website, I can create a payment once the user requests and I send him the redirect approval URL, after clients pay I call the execution on my backend with the payment ID and buyer ID, but I receive the error below

{"response":{"name":"VALIDATION_ERROR","message":"Invalid request - see details","debug_id":"4f3a6da7e0c7d","details":[{"location":"body","issue":"MALFORMED_REQUEST_JSON"}],"links":[],"httpStatusCode":400},"httpStatusCode":400}

I have been trying everything for a few hours, I tried to copy the create payment JSON from anywhere including PayPal API example and still, nothing works.

Also, I wanna redirect the client to success page just after transaction is approved (execute), it has to be handled by the front?

Code

const paypal = require('paypal-rest-sdk');
const dbService = require('../../services/mongodb-service');
const { ObjectId } = require('mongodb');

const getProducts = async () => {
    const products = await dbService.getCollection('products');
    return await products.find({}).toArray();
}

paypal.configure({
    'mode': 'sandbox',
    'client_id': 'id',
    'client_secret': 'secret'
});

const createPayment = async (productId) => {
    const products = await dbService.getCollection('products');
    const product = await products.findOne({ '_id': ObjectId(productId) })
    if (!product) return Promise.reject('Product not found');
    const payment = {
        "intent": "sale",
        "payer": {
            "payment_method": "paypal"
        },
        "transactions": [{
            "amount": {
                "currency": "USD",
                "total": product.price,
            },
            "description": product.description,
            "payment_options": {
                "allowed_payment_method": "IMMEDIATE_PAY"
            },
            "item_list": {
                "items": [{
                    "name": product.name,
                    "description": product.description,
                    "quantity": 1,
                    "price": product.price,
                    "tax": 0,
                    "sku": product._id,
                    "currency": "USD"
                }]
            }
        }],
        "redirect_urls": {
            "return_url": "http://localhost:3000/purchase-success",
            "cancel_url": "http://localhost:3000/purchase-error"
        }
    }
    const transaction = await _createPay(payment);
    const redirect = transaction.links.find(link => link.method === 'REDIRECT');
    return redirect;
}

const _createPay = (payment) => {
    return new Promise((resolve, reject) => {
        paypal.payment.create(payment, (err, payment) => err ? reject(err) : resolve(payment));
    });
}

const executePayment = async (paymentId, payerId) => {
    try {
        const execute = await _executePay(paymentId, payerId);
        console.log(execute);
        return execute;
    } catch (err) { console.log(JSON.stringify(err)) }
}


const _executePay = (paymentId, payerId) => {
    return new Promise((resolve, reject) => {
        console.log(paymentId, payerId);
        paypal.payment.execute(paymentId, payerId, (error, payment) => {
            return error ? reject(error) : resolve(JSON.stringify(payment));
        })
    })
}


module.exports = {
    createPayment,
    executePayment,
    getProducts
}

2

Answers


  1. Chosen as BEST ANSWER

    I was able to resolve it by doing a post request, code:

    const _executePay = async (paymentId, payerId) => {
        const response = await axios.post(`https://api.sandbox.paypal.com/v1/payments/payment/${paymentId}/execute`, { 'payer_id': payerId }, {
            auth: {
                username: CLIENT_ID,
                password: CLIENT_SECRET
            }
        })
        return response;
    }
    

  2. should be

    const _executePay = (paymentId, payerId) => {
        return new Promise((resolve, reject) => {
            console.log(paymentId, payerId);
    
            var payerIdObj = { payer_id: payerId };
    
            paypal.payment.execute(paymentId, payerIdObj, (error, payment) => {
                return error ? reject(error) : resolve(JSON.stringify(payment));
            })
        })
    }
    

    the doc

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search