Payment not automatically being captured, funds not transferred

EricJ4
New Community Member

Hi,

 

I'm attempting to implement a very simple flow for taking a $3 payment via a PayPal button.

 

Client-side code:

 

 

import { loadScript } from "@paypal/paypal-js"; async initialisePayPal() { const that = this; loadScript({ clientId: environment.paypal_client_id, components: "buttons", disableFunding: [ "card", "credit", "paylater", "bancontact", "blik", "eps", "giropay", "ideal", "mercadopago", "mybank", "p24", "sepa", "sofort", "venmo" ] }) .then((paypal) => { paypal.Buttons({ async createOrder(data, actions) { const result = await firstValueFrom( that.http.post(`${environment.api_url}/emp/paypal/order`, { userid: that.userid }, { headers: { 'x-api-key': environment.api_psk, } }), ) .then((order: any) => { return order.id; }) .catch(async (err) => { throw err; }); return result; }, onApprove: async (data, actions) => { // Capture the payment completion this.updateFeedbackTransaction(undefined, data.orderID); this.page = 3; } }).render('#paypal-button-container'); }) .catch((err) => { console.error("failed to load the PayPal JS SDK script", err); }); }

 

Server-side code:

 

async createPayPalOrder(userid: string) { const accessToken = await this.getPayPalToken(); const amount = { currency_code: "USD", value: this.DOLLAR_AMOUNT.toFixed(2), }; return await firstValueFrom( this.http.post( `${process.env.PAYPAL_BASE_URL}/v2/checkout/orders`, JSON.stringify({ intent: "CAPTURE", purchase_units: [ { description: "Feedback", amount: { ...amount, breakdown: { item_total: { ...amount, }, }, }, reference_id: userid, items: [ { name: "Feedback", quantity: 1, description: `February 2024`, category: "DIGITAL_GOODS", unit_amount: { ...amount, }, }, ], }, ], payment_source: { paypal: { experience_context: { payment_method_preference: "IMMEDIATE_PAYMENT_REQUIRED", payment_method_selected: "PAYPAL", brand_name: "My Brand Ltd", locale: "en-US", landing_page: "NO_PREFERENCE", shipping_preference: "NO_SHIPPING", user_action: "PAY_NOW", }, }, }, }), { headers: { "Content-Type": "application/json", Authorization: `Bearer ${accessToken}`, }, }, ), ) .then((res) => { return { id: res.data.id }; }) .catch(async (err) => { throw err; }); }

 

My intent is that, when the user presses the PayPal button, they log in and choose their funding method, and that takes the payment immediately. I thought that's how the CAPTURE intent was designed to work. However, on successful completion of the above, no funds are actually transferred.

 

This is the payment popup the user sees, and I would expect that clicking the "Complete Purchase" would transfer the funds.

 

 [Removed]

 

If I do a GET on the order at this point, I receive:

 

 

{    "id": "6YD62199GC2877623",    "intent": "CAPTURE",    "status": "APPROVED",    "payment_source": {        "paypal": {            "email_address": "email removed to allow posting",            "account_id": "SEHKQ4EVENTU2",            "account_status": "VERIFIED",            "name": {                "given_name": "John",                "surname": "Doe"            },            "address": {                "country_code": "US"            }        }    },    "purchase_units": [        {            "reference_id": "608bdb928950d2001b0450ab",            "amount": {                "currency_code": "USD",                "value": "3.00",                "breakdown": {                    "item_total": {                        "currency_code": "USD",                        "value": "3.00"                    }                }            },            "payee": {                "email_address": "email removed to allow posting",                "merchant_id": "K6RDTTU2TCZHJ",                "display_data": {                    "brand_name": "My Brand Ltd"                }            },            "description": "Feedback",            "items": [                {                    "name": "Feedback",                    "unit_amount": {                        "currency_code": "USD",                        "value": "3.00"                    },                    "quantity": "1",                    "description": "February 2024",                    "category": "DIGITAL_GOODS"                }            ]        }    ],    "payer": {        "name": {            "given_name": "John",            "surname": "Doe"        },        "email_address": "email removed to allow posting",        "payer_id": "SEHKQ4EVENTU2",        "address": {            "country_code": "US"        }    },    "create_time": "2024-02-27T11:28:53Z",    "links": [        {            "href": "https://api.sandbox.paypal.com/v2/checkout/orders/6YD62199GC2877623",            "rel": "self",            "method": "GET"        },        {            "href": "https://api.sandbox.paypal.com/v2/checkout/orders/6YD62199GC2877623",            "rel": "update",            "method": "PATCH"        },        {            "href": "https://api.sandbox.paypal.com/v2/checkout/orders/6YD62199GC2877623/capture",            "rel": "capture",            "method": "POST"        }    ] }

 

 


What am I doing wrong, and how can I make this capture and transfer funds as soon as the user chooses the Complete Purchase button? Thanks!

Login to Me Too
1 ACCEPTED SOLUTION

Accepted Solutions
Solved

EricJ4
New Community Member

Oh, I think I just need to do this, right?

onApprove: async (data, actions) => {
	// Capture the payment completion
	return actions.order.capture().then(function(details) {
		if(details.status === "COMPLETED") {
			that.updateFeedbackTransaction(undefined, data.orderID);
			that.page = 3;
		}
		else {
			alert("There was a problem with your payment. Please try again.");
		}
	});
	
}

 

That's weird because it was working a couple of weeks ago without this, but I guess something else has been changed somewhere in the meantime. 

View solution in original post

Login to Me Too
1 REPLY 1
Solved

EricJ4
New Community Member

Oh, I think I just need to do this, right?

onApprove: async (data, actions) => {
	// Capture the payment completion
	return actions.order.capture().then(function(details) {
		if(details.status === "COMPLETED") {
			that.updateFeedbackTransaction(undefined, data.orderID);
			that.page = 3;
		}
		else {
			alert("There was a problem with your payment. Please try again.");
		}
	});
	
}

 

That's weird because it was working a couple of weeks ago without this, but I guess something else has been changed somewhere in the meantime. 

Login to Me Too

Haven't Found your Answer?

It happens. Hit the "Login to Ask the community" button to create a question for the PayPal community.