Process an offsite payment
This guide shows you how to process a payment with an offsite payments app extension.
What you'll learn
Anchor link to section titled "What you'll learn"In this guide, you'll learn how to do the following tasks:
- Understand how the payment flow is initiated
- Resolve a payment
- Reject a payment
- Pend a payment
- Cancel a payment
- Take the next action after completing the payment flow
Initiate the flow
Anchor link to section titled "Initiate the flow"The payment flow begins with an HTTP POST request sent from Shopify to the payment session URL of your offsite payments app extension provided during app extension configuration. This request contains information about the customer and the order.
Shopify must receive an HTTP 2xx
response with redirect_url
(URL for the Partner page where Shopify redirects the customer) for the payment session creation to be successful.
If the request fails, then it's retried several times. If the request still fails, then the customer needs to retry their payment through Shopify checkout.
If there's an error on the payments app's side, then don't respond with an HTTP 2xx
. Use an appropriate error status code instead.
Request headers
Anchor link to section titled "Request headers"Header | Description |
---|---|
Shopify-Shop-Domain Required |
The permanent domain of the shop. Can be used to identify which shop is initiating the request. |
Shopify-Request-Id Required |
The unique request ID used to track specific requests for troubleshooting purposes. |
Shopify-Api-Version Required |
The API version selected in the payments app configuration. The version selected defines the response expected by the payments app. |
Request body
Anchor link to section titled "Request body"Attribute | Description | Type |
---|---|---|
id Required |
Unique identifier for the payment attempt. Used as the idempotency key. It can be assumed that requests with a given ID are identical to any previously received requests with the same ID. This ID must be surfaced to the merchant so that they can correlate Shopify orders with payments managed by the Partner app. | String |
gid Required |
Identifies the payment when communicating with Shopify (in GraphQL mutations, for example). | String |
group Required |
A customer might open multiple tabs in their browser for a given order. All of those tabs will be associated with the same group. As a result, Shopify can initiate multiple payment flows for the same id and group , redirecting to your app each time. Your app must only call the PaymentSessionResolve once per id and group . |
String |
amount Required |
The amount to be charged. The value is always sent using a decimal point as a separator, regardless of locale. | Numeric |
currency Required |
Three-letter ISO 4217 currency code. | String |
test Required |
Indicates whether the payment is in test or live mode. Refer to Test mode for more information. | Boolean |
merchant_locale Required |
IETF BCP 47 language tag representing the language used by the merchant. | String |
payment_method Required |
Hash giving details on the payment method used. Refer to payment_method hash for more information. | Hash |
proposed_at Required |
Can be used to order payment attempts that are a part of the same group. | String (ISO-8601) |
customer |
If customer is included, then at least one of customer.email or customer.phone_number is present. For more information on the customer field, refer to the customer hash. |
Hash |
kind Required |
Either sale or authorization . If you support payment authorization, then this value is set based on the merchant's configuration. If you don't support separate authorization and capture, then the value is always sale . For sale transactions, you need to capture the funds instantly with this request. For authorization transactions, you must place a hold on the funds and capture them later when Shopify sends a capture request. |
String |
payment_method
hash
Anchor link to section titled "payment_method hash"Attribute | Description | Type |
---|---|---|
type Required |
The type of payment method. Possible values: ["offsite" ]. |
String |
data Required |
Contains data relevant for the chosen payment method. Refer to payment_method.data hash for more information. | Hash |
payment_method.data
hash
Anchor link to section titled "payment_method.data hash"Attribute | Description | Type |
---|---|---|
cancel_url Required |
The URL to redirect the customer when the customer quits the payment flow and returns to the merchant's website. The cancel_url attribute should only be used when a customer is on the provider page and decides to cancel their payment and return to Shopify. |
String |
customer
hash
Anchor link to section titled "customer hash"Attribute | Description | Type |
---|---|---|
email |
The email of the customer. Required if phone_number isn't present. |
String |
phone_number |
The phone number of the customer. Required if email isn't present. |
String |
locale Required |
The language code as an ISO 639-1 string and the country code as an ISO 3166-1 Alpha-2 string, if available. For more information on the locale field, refer to the locale fields changelog. | String |
billing_address Required |
The billing address of the customer. Refer to shipping/billing_address hash for more information. | Hash |
shipping_address Required |
The shipping address for the order. Refer to shipping/billing_address hash for more information. | Hash |
shipping/billing_address
hash
Anchor link to section titled "shipping/billing_address hash"Attribute | Description | Type |
---|---|---|
given_name |
The given name or first name of the customer. | String |
family_name Required |
The surname of the customer. | String |
line1 Required |
First line of the customer's address (for example, the street or PO box). | String |
line2 |
Second line of the customer's address (for example, the apartment or suite). | String |
city Required |
Name of city or town. | String |
postal_code |
Zip or postal code. | String |
province |
Name of the province or state. | String |
country Required |
The country code as an ISO 3166-1 Alpha-2 string. | String |
phone_number |
The phone number of the customer. | String |
company |
Name of company. | String |
client_details
hash
Anchor link to section titled "client_details hash"Attribute | Description | Type |
---|---|---|
ip_address Required |
The IP address from the browser of the customer. | String |
user_agent Required |
The HTTP user-agent header from the browser of the customer. | String |
accept_language Required |
The HTTP accept-language header from the browser of the customer. | String |
Resolve a payment
Anchor link to section titled "Resolve a payment"You must use the paymentSessionResolve
mutation after the customer has successfully gone through the payment process. The id
argument corresponds to the global identifier (gid
) of the payment:
The redirectUrl
field is the URL to which the customer is to be redirected by the payments app.
Reject a payment
Anchor link to section titled "Reject a payment"The payments app should reject a payment if the customer can't complete a payment with the provider. The rejected payment tells Shopify that the checkout process will be halted. For example, if you don't want to process a high-risk payment, then you can reject the payment using the paymentSessionReject
mutation.
Rejecting a payment is final. You can't call other actions on a payment after it has been rejected.
The payments app should retry a failed user attempt and complete the payment before calling the paymentSessionReject
. For example, if any of the following conditions are met, then you don't need to reject the payment:
- The user doesn't interact with your payments app
- The user cancels the payment
- The user needs to retry the payment because of specific errors, such as user entering the wrong CVV
You can reject a payment using the paymentSessionReject
mutation, as shown in the following example:
The rejection requires information on why the payment was rejected. This information is encapsulated in the PaymentSessionRejectionReasonInput
.
The PaymentSessionRejectionReasonInput.code
is a PaymentSessionStatusReasonRejectionCode
enum of standardized error codes.
The PaymentSessionRejectionReasonInput.merchantMessage
argument is a localized error message presented to the merchant explaining why the payment was rejected.
Pend a payment
Anchor link to section titled "Pend a payment"You can pend a payment if it's awaiting asynchronous action by the customer, the payment Partner, or a payment network.
Not all payments can be processed and finalized quickly. Some payments can take several days to complete. Pending a payment indicates to the customer that you have started processing the payment, but require more time to complete the payment.
Upon completion, pending payments must be finalized into either a successful or failed state using the paymentSessionResolve
or paymentSessionReject
mutations. Both sale
and authorization
payments can be marked as pending.
To pend a payment, use the paymentSessionPending
mutation:
Cancel a payment
Anchor link to section titled "Cancel a payment"If a customer wants to cancel a payment on your provider page, then you can redirect the customer to the merchant's website or store by using the cancel_url
. The cancel_url
is sent to your payments app in the payment request that was sent from Shopify. You should not use the paymentSessionReject
mutation to cancel the payment, otherwise the customer will be unable to pay again with your provider. For more information on when to use the paymentSessionReject
mutation, refer to Reject a payment.
Next action
Anchor link to section titled "Next action"Upon receiving the response from either the paymentSessionResolve
, paymentSessionReject
, or paymentSessionPending
mutations, the next action that the payments app needs to perform is specified under nextAction
.
The nextAction will either be nil or contain two fields. In the case where it is nil, no next action is expected of the payments app.
Otherwise, the fields are as follows:
action
: APaymentSessionNextActionAction
enum that specifies the type of the action the app must perform.context
: Union type requiring inline fragments to access data on the underlying type. Takes a type ofPaymentSessionActionsRedirect