General Requirements
This version includes improvements to the Client Session API, Payments API and the Payment Methods API. You must set theX-Api-Version header to 2.4 to use v2.4 of the API.
SDK Requirements
To test API v2.4 you must opt-in to use the specific version within the Checkout SDKs.Web
Available in Web SDK v2.50.0 and later.To use API version 2.4, use the
UniversalCheckoutOptions.apiVersion property when initializing the checkout.
iOS
Available in iOS SDK v2.34.0 and later. To use API version 2.4, set the apiVersion tov2_4 in your PrimerSettings before initializing the checkout.
Android
Available in Android SDK v2.35.0 and later. To use API version 2.4, set the apiVersion tov2_4 in your PrimerSettings before initializing the checkout.
React Native
Available in React Native SDK v2.30.0 and later. To use API version 2.4, set the apiVersion to2.4 in your PrimerSettings before initializing the checkout.
Payment Types
OurpaymentType field is used to send the correct information to processors for payment method storage, recurring and credential-on-file payments.
In API v2.4 we have changed the way this field is calculated and also upgraded our related recurring payments logic to be more accurate and intuitive. You can read more about how it works in our guide to optimizing recurring payments.
If you process merchant-initiated payments or allow customers to store their payment methods for easier checkout, this change directly impacts you. We strongly recommend upgrading to benefit from the improved logic and ensure seamless processing.
paymentType based on the type of payment flow. However, if you do not pass one, we will calculate the most likely down stream value required from context.
Payment Types – Main changes
If you do not pass apaymentType when creating a payment, we will no longer assign it a value. Instead the paymentType field will remain blank and our improved internal logic will send the best possible information to your end processor(s).
This is in contrast to previous API versions, where if a paymentType was not passed, a value was calculated and passed back based on whether the payment method had been previously vaulted and whether any intention to vault was passed.

These changes bring the following improvements:
- 
Resolves a known issue where payments made without a 
paymentTypeinitiated by customers using a previously vaulted card were flagged aspaymentType : UNSCHEDULED– these will now remain with a nullpaymentTypevalue. This will also ensure that the Payment Initiation Type in the “Payment created” Trigger can be relied on to route these payments correctly. - 
Resolves a known issue where one-off payments made without a 
paymentTypewere incorrectly marked asECOMMERCE– these will now remain with a nullpaymentTypevalue. - 
Vaulted payment methods will be passed to the end processor with the correct processor specific fields, regardless of whether a 
paymentTypeis passed through or if the incorrect value is used.- This is particularly relevant when using our Drop-in, where customers can select a Vaulted payment method without the front end being explicitly notified, which can result in invalid 
paymentTypevalues being used. 
 - This is particularly relevant when using our Drop-in, where customers can select a Vaulted payment method without the front end being explicitly notified, which can result in invalid 
 - 
Payment methods that cannot be vaulted will never be passed to the end processor with an instruction to vault, regardless of what 
paymentTypeis passed through. 
Optional Parameter Addition – First Payment Reason
An optional field,firstPaymentReason, has been added to the  paymentMethod object, directly related to the paymentType logic:
- The enum 
firstPaymentReasonallows you to indicate why a payment method is being vaulted when settingpaymentType : firstPayment, with three possible values ofCardOnFile,Recurring, andUnscheduled. Pass this field if using a processor that has strict requirements for card storage. 
Migration Steps – Payment Types
- 
Check current 
paymentTypebehavior- Ensure you’re passing the most logical 
paymentTypewhen creating or patching a client session and creating a payment. 
 - Ensure you’re passing the most logical 
 - 
Check if 
firstPaymentReasonwould benefit your payments- If you’re vaulting payment methods with 
paymentType: firstPayment, consider including the new parameterfirstPaymentReasonand setting it according to why the payment is being stored. 
 - If you’re vaulting payment methods with 
 - 
Review Workflow Logic
- Check your Primer workflows and ensure any changes do not impact your workflow logic.
 - In particular, check if you’re currently using the Transaction Type input or output in your workflow routing, as this correlates to the 
paymentTypeparameter. 
 - 
Test and Validate
- Use the sandbox environment to test your new implementation and ensure it continues to operate as expected with your Primer workflow logic and any internal requirements.
 
 
Timeout Management Improvements
We have extended our payment API timeout from 25s to 90s, with a maximum processor timeout allowance of 60 seconds. Our SDK timeout remains at 15 seconds, to limit impacts on the customer experience. The longer timeframe allows ample time for external processors with long timeout values to respond – the average maximum timeout allowance from processors is between 60 and 70s – while also allowing any additional internal operations by the Primer engine. This will minimize synchronization issues when a timeout occurs with an external processor, ensuring you can maintain full visibility of your payments within the Primer ecosystem. To support this change, we have added a new Decision Type ofGATEWAY_TIMEOUT. This will be returned when an external processor returns a timeout error or does not respond within our maximum processor timeout allowance.
The 
GATEWAY_TIMEOUT Decision Type is not included in fallback trigger reasons to avoid scenarios where a customer may inadvertently be charged twice. Once you have upgraded your workflows, processor timeouts will be excluded from fallback logic.Migration Steps – Timeouts
- 
Check what your own internal timeout values for Primer are set to
- 
If you have a timeout value shorter than 90s set on your end, you may wish to:
- Amend it to be in line with our new values, or
 - Add additional logic if the timeout value is hit to perform a 
GETrequest for the payment status at a later time 
 - This is particularly relevant if you’re using the manual payment creation flow, as the potential time a payment may take to complete has now increased.
 
 - 
If you have a timeout value shorter than 90s set on your end, you may wish to:
 - 
Ensure the addition of a new Error Decision Type will not break your integration
- The 
GATEWAY_TIMEOUTvalue is additive, so should not break any existing implementation. However if your integration is hardcoded to the API ≤v2.3 values for Error Decision Type, or if any of your own internal logic explicitly relies on those values, you will need to update your mappings to ensure no errors occur. 
 - The 
 - 
Review Workflow Logic
- Check your Primer workflows and ensure any changes do not impact your workflow logic.
 - In particular, check if you’re currently using the Error Decision Type input or output in your workflow routing, as this will now include a new option and you will need to ensure it’s accounted for in your logic.
 
TheGATEWAY_TIMEOUTvalue will not appear in your workflow outputs until you update to the latest version of the workflow action. Please ensure you follow these steps before updating. - 
Test and Validate
- Use the sandbox environment to test your new implementation and ensure it continues to operate as expected with your Primer workflow logic and any internal requirements.
 
 
Partial Captures and Targeted Refunds
We are introducing partial captures and targeted refunds to address key reconciliation and payment workflows for marketplaces. These changes enable you to:- Refund specific items or captures without affecting unrelated payments
 - Align payments with logistics and marketplace sellers, and track seller payments and performance with unique transaction capture IDs
 
transactions.events in the Payment Object:
- Each partial capture generates a unique 
transactionEventId, used in the reconciliation file - You can choose to receive a list of transaction events for captures and other updates, by expanding the request:
/payments/{id}?expand=transactions.events 
- When performing a refund, you can specify the 
transactionEventIdto target the partial capture. 
How Partial Captures and Targeted Refunds Work
Each partial capture generates a unique transactionEventId, which is the key to track partial captures and to handle targeted refunds. This ID is included in reconciliation files and API responses. To process targeted refunds (a refund on a specific partial capture), you need to storetransactions.events.id in your system. This ID ensures you reference the right capture when making a refund.
Partial Captures and Refunds – Main changes
- Add the 
transactions.eventsarray to the Payment API, within the transaction object. - Update accordingly the GET payments, POST refund and POST capture endpoints
 - Use 
expand=transactions.eventsto get transaction event details. - Remove 
processorData.external_ids, includingauthorization_id, from API and webhook payloads. 
Using Partial Captures and Refunds
Making a Partial Capture
- Every partial capture generates a 
transactionEventId. - This ID is included in reconciliation files and API responses.
 - To get a list of transaction events for captures and updates, use:
 
Issuing a Targeted Refund
- Include the 
transactionEventIdin the refund request to target a specific capture. 
Retrieving Transaction Events
- When a payment update is received, you can retrieve transaction event details:
 
Example Workflow
- Receive a webhook for a payment update:
 
- Retrieve transaction events to find 
transactionEventId: 
- For each Capture or Refund request, if you receive a synchronous response from the PSP, you can also expand the transaction events by including:
 
Example API Responses
Partial Capture details from a GET Payment call with ?expand=transactions.events
Targeted Refund details from a GET Payment call with ?expand=transactions.events
Migration Steps – Targeted Refunds
- 
Update Data Handling
- Stop using 
processorData.external_idsin API responses. - Use API calls to fetch transaction events instead.
 
 - Stop using 
 - 
Store 
transactionEventId- Ensure your system maps 
transactions.events.idto internal records. - Use this ID when issuing targeted refunds.
 
 - Ensure your system maps 
 - 
Adapt Webhook Changes,
If you were relying on web hooks to retrieve external ids, the external_id field will no longer be included in webhook payloads. Instead you now need to:
- Receive the webhook.
 - Perform a GET request with 
?expand=transactions.eventsto retrieve theprocessorEventIdof the event, replacing the old external_id field. 
 - 
Adjust Refund Workflows
- Always include 
transactionEventIdwhen issuing refunds. - Update reconciliation to handle event-based refunds.
 
 - Always include 
 - 
Test and Validate
- Use the sandbox environment to test partial captures and refunds.
 - Verify API calls to ensure correct event tracking.
 
 
Parameter addition – Vault On Agreement
The booleanvaultOnAgreement allows you to vault a payment method when an agreement mandate completes successfully in supporting processors (e.g., ACH via Stripe). Pass true to store customer payment methods in the Primer Vault for future billing in payment processors that rely on Agreement flows, like ACH via Stripe.