'PayPal order capture returns UNPROCESSABLE_ENTITY TRANSACTION REFUSED

I am using PayPal hosted payment fields to attempt to accept cards on my app. On sandbox, everything works perfectly fine. I can create orders, capture them, and go about my day. This is not true for the production environment.

I am using this format to create the paypal order:

        let request = new paypal.orders.OrdersCreateRequest();
        request.prefer("return=representation");
        request.requestBody({
            intent: "CAPTURE",
            purchase_units: [{
                amount: {
                    currency_code: "USD"
                    value: "20.05"
                }
            }]
            application_context: {
                shipping_preference: "NO_SHIPPING"
            }
        });

Attempting to capture the order with any card I have results in this:

HttpError: {"name":"UNPROCESSABLE_ENTITY","details":[{"issue":"TRANSACTION_REFUSED","description":"The request was refused"}],"message":"The requested action could not be performed, semantically incorrect, or failed business validation.","debug_id":"ee2fb8a7de388","links":[{"href":"https://developer.paypal.com/docs/api/orders/v2/#error-TRANSACTION_REFUSED","rel":"information_link","method":"GET"}]}

I have tried this with about half a dozen credit/debit cards. They all get put down as an unprocessable entity. Originally I thought there must be something wrong with my business account itself. What I've found is that

  1. Accepting payments in USD

  2. Approved for advanced debit/credit card payments

  3. Using the live credentials for the live app

  4. Address of account is in US

I can't for the life of me figure out why the transaction is refusing. I checked with my bank and the funds are transferring out, and then back in after paypal refuses the transaction. Am I not providing sufficient information or something?

This is my capture for reference:

    var orderID = req.body.order;

    const request = new paypal.orders.OrdersCaptureRequest(orderID);
    request.requestBody({});

    try {
        const capture = await client.execute(request);

        console.log(capture);
        console.log(capture.result.payment_source)
        console.log(capture.result.purchase_units)

        //const captureID = capture.result.purchase_units[0].payments.captures[0].id;

        //console.log(captureID);

        //save captureID to database

        //await Capture.create({paypal_capture_id: captureID, order_id: capture.result.id})

        res.status(200).json(capture);

    } catch (err) {
        console.error(err);
        return res.status(400).json(err);
    }

Edit: Here is the billing address information:

var billingAddress = {

                streetAddress: billing_address_info.address.split(',')[0],
                // State
                region: billing_address_info.address.county,
                // City
                locality: billing_address_info.address.city,
                // Postal Code
                postalCode: billing_address_info.address.postal,
                // Country Code
                countryCodeAlpha2: lookup.byCountry(billing_address_info.country).iso2
            }

This logs as

{
    "streetAddress": "xxx",
    "extendedAddress": "xxx",
    "region": "xx",
    "locality": "xxxxx",
    "postalCode": "xxxxx",
    "countryCodeAlpha2": "xx"
 }

In my case the billing address is always some US validated address.

   if (
            Object.values(hostedFields.getState().fields).some(
                (field) => !field.isValid
            ) ||
            !cardHolderName
        ) {
            return alert(
                "The payment form is invalid, please check it before execute the payment"
            );
        }
    setPaying(true)
    hostedFields
        .submit({
            // The full name as shown in the card and billing address
            cardholderName: cardHolderName,
            billingAddress: billingAddress
        })
        .then(async (order) => {

            console.log(order)
            onApprove(order)
    
        })
        .catch((err) => {
            setPaying(false)
            console.log(err)
            console.log(err.response.data)
        })


Solution 1:[1]

Is this Hosted Fields as in Advanced Credit and Debit Cards, or just the black Debit or Credit Card button? If the former, are you including a full billing address in card form submission before the capture? Show that part of your code.

TRANSACTION_REFUSED is a normal decline response by PayPal, and generally does not indicate an integration or technical problem, but rather that card being suspect in some way. If it's not the lack of a billing address w/Advanced fields, it may actually be the half dozen cards you're testing with are being refused for some reason, such as if they're somehow detected as being connected to the receiver account. Paying your own account in production is actually not permitted, though it's understandable why you'd want to verify it's working before putting it to a 'real customer' card.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Preston PHX