General transaction requirements

Payments apps must operate in accordance with the following general requirements for transactions, including support for test mode.

mTLS configuration

Payments apps must implement mTLS to handle all* requests where they are acting as the server and Shopify as the client. This is the case when Shopify initiates sessions with payments apps. In those cases, Shopify uses it's own client certificate. Payments apps must use the self-signed CA provided below in order to validate that certificate. Using mTLS in these scenarios allows payments apps to verify that the client initiating the request is Shopify and that the traffic between Shopify and the payments app is trusted and secure.

Because mTLS is mutual, the payments app also needs to provide a certificate that Shopify will validate. For this certificate, you need to use a Trusted CA Signed SSL Certificate, and not Shopify’s self-signed CA.

Shopify's Payments Platform Root CA

Shopify's Payments Platform Secondary CA Production

Idempotency

Payments Apps APIs support idempotency, which allows Shopify to safely retry requests without accidentally performing the same operation twice. It's critical in cases where there are network errors to prevent, such as multiple charges for the same payment.

Payments Apps APIs (HTTP requests from Shopify to your app)

You need to support idempotent requests for the Payments Apps APIs. Regardless of how many requests with the same idempotency key are sent, the result must be the same. The idempotency key attributes are defined on a per-API basis.

GraphQL mutations (requests to Shopify)

Idempotency is implemented, for a given id, at a per operation name level. If multiple mutation requests of the same name are sent, then the operation is performed only once and the same response is returned. For example, this would occur if several PaymentSessionResolve requests were sent with the same id.

If requests with different names are sent with the same id, then only the first request is processed. For example, if both a PaymentSessionResolve and PaymentSessionReject request are sent for the same payment id, then the PaymentSessionResolve request is processed, and the PaymentSessionReject request fails and returns a user_error.

Retry policy

Due to the asynchronous nature of Shopify's Payments Apps APIs, you must send a GraphQL request to notify Shopify of the results of any payment or refund requests. A retry policy helps provide data consistency between merchants, partners, and Shopify.

If you don't receive an acknowledgment of a GraphQL request (HTTP 200 status code), then you must retry the request according to the following incremental strategy, up to a total of 18 retries over 24h.

Parameter Description Value
Number of recommended retries The maximum number of recommended retries. 18
Base delay interval The time interval after which the first retry is attempted. 5 seconds
Exponential backoff factor Partners are expected to retry their requests immediately, and then 5 seconds afterwards, and then at increasing time intervals after that, until the request is acknowledged or 24 hours has passed, whichever comes first. See example

Example:

[0 seconds, 5 seconds, 10 seconds, 30 seconds, 30 seconds, 45 seconds, 1 minute, 2 minutes, 5 minutes, 12 minutes, 38 minutes, 1 hour, 2 hours] + [4 hours] * 5

You must implement a retry policy for the Payments Apps API mutations.

Rate limiting

To protect the stability of the platform, payments apps are rate-limited. For more information, refer to Shopify API rate limits.

Next steps

Additional information