Skip to content
Blog

9 min read

PayPal in Lovable: check the payment flow before launch

Lovable's PayPal integration simplifies checkout, but your app must still handle charges, statuses and refunds correctly.

By Written with AI assistance from the source

Mist over dark rocks on a calm coast
Photo: atelierbyvineeth ... on Unsplash

What has changed

On 8 November 2026, Lovable added an integration that allows an app to use an existing PayPal account. According to Lovable's changelog, the app can create a checkout, capture an approved order, issue refunds and retrieve order information.

The integration is suitable for uses such as a shop, donation page, ticket sales or bookings where the customer pays a deposit. You can add it from Connectors in Lovable or ask Lovable to connect PayPal in the project chat.

This is a connector to your own PayPal account, not the same feature as Lovable's built-in payment solution. The money goes to the account you connect, and PayPal handles its fees and payment administration. For live payments, you need a verified PayPal business account and a PayPal REST app with production credentials.

Lovable allows you to create separate connections for sandbox and live environments. This matters because PayPal uses different REST apps and credentials for testing and production. Give the connections clear names, such as PayPal Sandbox and PayPal Live, to reduce the risk of linking the wrong environment to the project.

The connector handles some of the technical infrastructure. The PayPal secret must not reach the visitor's browser, and requests pass through Lovable's connector gateway. Lovable's documentation also states that messages from PayPal are verified before the app acts on them. However, the connector does not decide when your own order should count as paid, when a ticket should be sent or how a failed refund should be displayed. That logic still needs to be clear in the app.

Approval is not the same as capture

The most important point to understand is that a PayPal checkout contains separate events.

First, the app creates an order and sends the customer to PayPal. The customer signs in, reviews the purchase and approves it. The app's server must then request that the payment be captured. This is when the charge is made.

The status APPROVED therefore does not mean that you have definitely been paid. It means that the customer has approved the order with PayPal. Your app should treat the purchase as paid only after the capture has succeeded and the payment has the status COMPLETED.

This should not be confused with PayPal's separate AUTHORIZE intent, which is used to reserve funds for a later charge. Lovable's connector describes a flow in which an approved order is captured after checkout. The customer's approval is therefore part of the checkout, not proof that a capture has been completed.

A common but risky implementation is to display a thank-you page and mark the order as paid as soon as the customer returns from PayPal. The return only shows that the browser has navigated back. The customer can reload the page, open the same return address again or arrive there even if the server request failed.

The server should therefore check the order and carry out the capture. While this happens, the interface can show that the payment is being processed. Delivery, booking confirmation, a ticket or any other entitlement should be activated only when the app has a confirmed payment status.

Model status in your own database

Do not store only a Boolean column such as paid. Payments can remain pending, fail and be partially refunded. A single on-or-off status loses important information and makes support, reconciliation and troubleshooting more difficult.

A simple local model could look like this:

Local statusMeaningWhat the app should do
awaiting_approvalThe customer has not yet approved the PayPal orderAllow the customer to continue or cancel the checkout
approvedThe customer has approved the order, but capture is not confirmedShow that the payment is being processed and do not deliver
payment_pendingPayPal is processing the paymentWait for a new status and keep the order reserved according to your own rules
paidCapture is confirmed as completeConfirm the purchase and start delivery
payment_failedCapture was declined or failedShow a clear error and offer another payment attempt
partially_refundedPart of the payment has been refundedShow the refunded and remaining amounts separately
refundedThe payment has been refundedClose the financial part of the order without deleting its history
cancelledThe checkout was cancelled or the order should no longer be paidRelease any reservation and retain the event history

Also store PayPal's order ID, capture ID and refund ID when available. They identify different objects and are needed to retrieve the correct event. A refund is made against a capture, not just your internal order number.

It is also useful to retain PayPal's raw status alongside your local status. This allows your app to use clear internal terms without discarding information needed for troubleshooting. Also record when the status was last checked and which event caused the change.

PayPal can send status updates through webhooks. A webhook is a message from PayPal to your server when something happens without a user actively loading a page. The handling should allow for the same message to arrive more than once. If an update has already been processed, the app must not send another ticket, reduce stock again or repeat a refund.

The list of recent transactions should not be used as immediate confirmation during checkout. Lovable states that it may be updated after a delay and that Transaction Search must be enabled in PayPal's REST app. Use the order and capture status for the current purchase instead.

Handle refunds as separate events

Lovable's connector can issue both full and partial refunds. This does not mean that the app should immediately change the order to refunded when someone presses a button.

A refund has its own lifecycle and can be pending, completed, failed or cancelled. Create a separate record for each refund attempt. Store the capture ID used, who initiated the action, the reason, the status and PayPal's refund ID.

For a partial refund, the app must also total previous refunds. Otherwise, an administrator may try to refund more than the remaining amount. The interface should show the original payment, the amount already refunded and the amount that can still be refunded.

Make the refund function idempotent. This means that a repeated request with the same intent must not create the same financial action again. This is particularly important when a network error means the app does not know whether PayPal processed the request. Check the current status before trying again and reuse a unique reference for the same operation if the implementation supports it.

Also account for refunds made directly in PayPal's administration interface. Otherwise, your database may continue to show the order as paid even though the money has been returned. Make sure that the webhook flow or scheduled reconciliation detects external changes.

The refund is the technical movement of money. What should happen at the same time to a booking, ticket, donation or delivery is a separate business rule. A refunded payment does not automatically tell the app whether a place should be released, a ticket blocked or an order stopped.

Test the entire flow in the sandbox

Start with PayPal's sandbox and link only the sandbox connection to the test project. Use separate test accounts for the seller and buyer. Check the outcome both in the app's database and in PayPal's test environment, not just through what the interface displays.

Work through the following situations:

  • The customer approves the checkout and capture completes before the order is marked as paid.
  • The customer cancels with PayPal and returns without the order being activated.
  • The customer approves the order, but capture remains pending or fails.
  • The return page is reloaded without repeating the capture or delivery.
  • The payment button is pressed several times without creating parallel order flows.
  • The same webhook is processed again without duplicate messages or status changes.
  • A full refund updates both the payment and the order view.
  • A partial refund leaves the correct remaining amount.
  • A refund issued through PayPal's own interface later appears in the app.
  • A missing, deleted or incorrectly linked connector produces a clear error.
  • A user without the correct permissions cannot issue refunds.
  • The logs contain useful IDs but never the PayPal secret.

Ask Lovable to describe the generated payment flow in plain language: where the order is created, where capture takes place, which database fields change and which webhook events are handled. Then ask Lovable to add tests for reloading, repeated requests and failed responses. A checkout working in the standard successful case says little about how the app behaves when the network or PayPal responds unexpectedly.

Check this before accepting live payments

Once the sandbox flow is stable, create a separate live connection using credentials from PayPal's production environment. Disconnect the sandbox from the project before linking the live connection, and verify that the published code uses the correct connector.

Carry out a final check:

  • The secret exists only in the connector and is not exposed in client code, logs or database tables.
  • The amount, currency and contents are calculated or validated on the server.
  • An order is not marked as paid merely because the customer reaches the return page.
  • Delivery takes place only after a confirmed capture.
  • Pending and failed payments have clear user-facing messages.
  • Capture and refunds can be retried without duplicate financial events.
  • Webhooks can be received, verified and processed safely more than once.
  • Manual changes in PayPal can be reconciled with your database.
  • Only the correct roles can view payment details and initiate refunds.
  • The support view shows PayPal's order, capture and refund IDs.

Then carry out a controlled live transaction and follow it through approval, capture, local order status and refund. Check what the customer sees at each stage and what an administrator can use to understand the sequence of events.

The PayPal connector reduces the work involved in the API integration itself, but a reliable payment flow still requires clear states, secure server-side decisions and tested failure paths. When payments need to become a dependable part of the whole service, the next step is to move from prototype to product.


Source: Lovable changelog

Want to know what your build would take?

Three questions, then you get a clickable sketch for free.

← All articles