Primer Payments API

REST API for creating and managing payments, client sessions, and saved payment methods. Supports the full payment lifecycle including authorization, capture, refund, cancellation, and dispute management. Versioned via X-Api-Version header with current GA version 2.4.

OpenAPI Specification

primer-payments-openapi.yml Raw ↑
openapi: 3.0.2
servers:
  - url: https://api.sandbox.primer.io
  - url: https://api.primer.io
info:
  x-logo:
    url: https://apidocs.primer.io/docs/assets/images/primer-logo.svg
  title: Primer API
  version: '2.4'
  description: >-
    This API enforces a timeout of 90 seconds for all requests. A 504 response indicates
    a timeout occurred.

x-readme:
  explorer-enabled: true
  samples-languages: [curl, javascript, python, kotlin, swift]
  headers: [{key: X-API-VERSION, value: '2.4'}]
security:
  - ApiKeyAuth: []

tags:
  - name: Client Session API
  - name: Payments API
  - name: Payment Methods API
  - name: Observability API (beta)

paths:
  /client-session:
    post:
      tags:
        - Client Session API
      summary: Create a client session
      description: |
        Creating a client session generates a client token: a temporary key used to initialize [Universal Checkout](/docs/get-started/set-up-a-checkout) and authenticate it against your account.

        Universal Checkout automatically retrieves all the settings from the client session and the Dashboard to configure the payment methods and the checkout experience.

        <b>Note:</b>
        When creating a Client Session, please make sure to provide `currencyCode`, `orderId`, and at least one of `amount` or `lineItems`. 
        If any of these are not yet available, you can provide them when making the payment request.

        <code>POST /client-session</code> does not have required fields as all fields are not always known when a client session is created. 
        Use <code>PATCH /client-session</code> to update the parameters throughout the checkout session.

        Client tokens expire after 24 hours.

      operationId: create_client_side_token_client_session_post
      parameters:
        - $ref: '#/components/parameters/ApiVersionHeader'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ClientSessionAPIRequest'
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ClientSessionWithTokenAPIResponse'
        '400':
          description: Error Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/400ErrorResponse'
              examples:
                ClientSessionValidationError:
                  summary: The client token is invalid.
                  value:
                    error:
                      errorId: ClientSessionValidationError
                      description: The client token is invalid.
                      recoverySuggestion: Please provide a valid client token.
                      diagnosticsId: '1234567898'
                MetadataContainsEmptyKey:
                  summary: Metadata field contains empty string key.
                  value:
                    error:
                      errorId: MetadataContainsEmptyKey
                      description: Metadata field contains empty string key.
                      recoverySuggestion: >-
                        Either remove empty string keys or provide non-empty string
                        instead.
                      diagnosticsId: '1234567898'
        '422':
          description: Error Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/422ErrorResponse'
              example:
                error:
                  errorId: RequestValidationError
                  description: >-
                    We were unable to validate your request, please check your payload
                    against /docs/api
                  diagnosticsId: '1234567898'
                  validationErrors: [{model: ClientSessionAPIRequest, errors: [{
                                path: $.customerId, description: Value must be a
                                valid string}]}]
    get:
      tags:
        - Client Session API
      summary: Retrieve a client session
      description: |
        This API call retrieves all the details associated with the client session corresponding to the client token that is provided in the request. The fields with empty values are excluded from the response.

      operationId: retrieve_client_side_token_client_session_get
      parameters:
        - description: Client token corresponding to the client session to 
            retrieve
          schema:
            title: Client Token
            type: string
            description: Client token
          name: clientToken
          in: query
        - $ref: '#/components/parameters/ApiVersionHeader'
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ClientSessionAPIResponse'
        '400':
          description: Error Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/400ErrorResponse'
        '422':
          description: Error Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/422ErrorResponse'
    patch:
      tags:
        - Client Session API
      summary: Update client session
      description: |
        You can update a clients session created earlier with the `PATCH /client-session` [API call](#operation/create_client_side_token_client_session_post).

        The only required field for the request is `clientToken`. Other supported request fields are same as for the `POST /client-session` [API call](#operation/create_client_side_token_client_session_post).

        You need to specify only the fields you wish to update. However, if the items to be updated are arrays (e.g.`lineItems`), you need to provide the entire array, including any new or modified items. Primer will replace the full array with whatever is sent in the request. If you want to keep existing items, make sure to include them in your request, anything omitted will be removed.

        If you wish to update nested fields on the client session, such as the customer `emailAddress` field, you can pass the `customer` object with only one field, `emailAddress`, to update.

        If you simply wish to clear the value of the field, pass `null` as your input.

        You can update `paymentMethod.vaultOnSuccess` field but updating of the `paymentMethod.options` field through `PATCH /client-session` is not supported.

        The response will contain all the fields of the client session including the ones that were changed.

      operationId: update_client_side_token_client_session_patch
      parameters:
        - $ref: '#/components/parameters/ApiVersionHeader'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ClientSessionUpdateAPIRequest'
              title: Request
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ClientSessionAPIResponse'
        '400':
          description: Error Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/400ErrorResponse'
              examples:
                ClientSessionValidationError:
                  summary: The client token is invalid.
                  value:
                    error:
                      errorId: ClientSessionValidationError
                      description: The client token is invalid.
                      recoverySuggestion: Please provide a valid client token.
                      diagnosticsId: '1234567898'
                MetadataContainsEmptyKey:
                  summary: Metadata field contains empty string key.
                  value:
                    error:
                      errorId: MetadataContainsEmptyKey
                      description: Metadata field contains empty string key.
                      recoverySuggestion: >-
                        Either remove empty string keys or provide non-empty string
                        instead.
                      diagnosticsId: '1234567898'
        '422':
          description: Error Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/422ErrorResponse'

  /payments:
    get:
      tags:
        - Payments API
      summary: Search & list payments
      description: |
        <p/>

        Retrieve a list of your payments.

        Results are paginated, they will only return up to 100 payments maximum.
        To access the next page of result, set the `cursor` query parameter to the value of `nextCursor` in
        your current result payload. Use `prevCursor` to go back to the previous page.

        **Note:** this endpoint returns a list of
        summarized payments. Not all payments attributes are present. You can use
        the query parameters to filter payments. You can separate multiple query parameters with the `&` symbol.
        Query parameters with types of the form "Array of strings" (such as the status parameter) can be specified as a comma-separated list.

        For example, if you wanted to get both `FAILED`  and `CANCELLED` payments, for customer `john-123`, you would use:
        ```bash
        curl --location --request GET 'https://api.primer.io/payments?status=FAILED,CANCELLED&customer_id=john-123' \
        --header 'X-Api-Key: <YOUR_API_KEY>'
        ```

        You can alternatively specify a list by repeating the parameter multiple times.

        **Note:** payments will be available within a minute from being created.

      operationId: list_payments_payments_get
      parameters:
        - description: Filter payments by their status.
          required: false
          schema:
            title: Payment status
            type: array
            items:
              $ref: '#/components/schemas/PaymentStatus'
            description: Filter payments by their status.
          name: status
          in: query
        - description: Filter payments by their payment method type.
          required: false
          schema:
            title: Payment method type
            type: array
            items:
              $ref: '#/components/schemas/PaymentMethodTypeEnum'
            description: Filter payments by their payment method type.
          name: payment_method_type
          in: query
        - description: Filter payments by their payment processor.
          required: false
          schema:
            title: Payment processor
            type: array
            items:
              type: string
            description: Filter payments by their payment processor.
          name: processor
          in: query
        - description: |
            Filter payments by their payment currency.
            e.g. use `USD` for US dollars.
          required: false
          schema:
            title: Payment currency
            type: array
            items:
              type: string
            description: |
              Filter payments by their payment currency.

              Use the 3-letter currency code in [ISO 4217 format](https://en.wikipedia.org/wiki/ISO_4217#Active_codes).
              e.g. use `USD` for US dollars."
          name: currency_code
          in: query
        - description: Return only payments from this date (inclusive).
          required: false
          schema:
            title: Payment date
            type: string
            description: Return only payments from this date (inclusive).
            format: date-time
          name: from_date
          in: query
        - description: Return only payments up to this date (inclusive).
          required: false
          schema:
            title: Payment date
            type: string
            description: Return only payments up to this date (inclusive).
            format: date-time
          name: to_date
          in: query
        - description: Return payments related to this order ID.
          required: false
          schema:
            title: Payment order ID
            type: string
            description: Return payments related to this order ID.
          name: order_id
          in: query
        - description: Return payments of this amount minimum (inclusive).
          required: false
          schema:
            title: Payment amount
            type: integer
            format: int64
            description: Return payments of this amount minimum (inclusive).
          name: min_amount
          in: query
        - description: Return payments of this amount max (inclusive).
          required: false
          schema:
            title: Payment amount
            type: integer
            format: int64
            description: Return payments of this amount max (inclusive).
          name: max_amount
          in: query
        - description: ID of the customer that has made the payment.
          required: false
          schema:
            title: Customer ID
            type: array
            items:
              type: string
            description: ID of the customer that has made the payment.
          name: customer_id
          in: query
        - description: ID of the merchant involved in the payment.
          required: false
          schema:
            title: Merchant ID
            type: array
            items:
              type: string
            description: ID of the merchant involved in the payment.
          name: merchant_id
          in: query
        - description: Email of the customer that has made the payment.
          required: false
          schema:
            title: Customer email address
            type: array
            items:
              type: string
            description: Email of the customer that has made the payment.
          name: customer_email_address
          in: query
        - description: Last 4 digits of the card used for the payment.
          required: false
          schema:
            title: Last 4 digits
            type: array
            items:
              type: string
            description: Last 4 digits of the card used for the payment.
          name: last_4_digits
          in: query
        - description: Paypal email address associated with the payment.
          required: false
          schema:
            title: Paypal email
            type: array
            items:
              type: string
            description: Paypal email address associated with the payment.
          name: paypal_email
          in: query
        - description: Klarna email address associated with the payment.
          required: false
          schema:
            title: Klarna email
            type: array
            items:
              type: string
            description: Klarna email address associated with the payment.
          name: klarna_email
          in: query
        - description: Maximum number of payments to return per page.
          required: false
          schema:
            title: Limit result set
            maximum: 100.0
            minimum: 1.0
            type: integer
            format: int64
            description: Maximum number of payments to return per page.
            default: 100
          name: limit
          in: query
        - description: >-
            If results are paginated, pass the `nextCursor` to access next page.
          required: false
          schema:
            title: Page cursor
            type: string
            description: >-
              If results are paginated, pass the `nextCursor` to access next page.
          name: cursor
          in: query
        - $ref: '#/components/parameters/ApiVersionHeader'
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaymentListAPIResponse'
        '422':
          description: Error Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/422ErrorResponse'
              example:
                error:
                  errorId: RequestValidationError
                  description: Invalid type for `currencyCode`
                  recoverySuggestion: The currency code must be a valid value
                  diagnosticsId: '1234567898'
    post:
      tags:
        - Payments API
      summary: Create a payment
      description: |
        <p/>

        Create and authorize a payment for a given customer order. You
        should provide a payment method token here to avoid PCI implications.

        If only a payment method token is passed, the values passed with the Client Session is used to determine the amount, currency etc.
        Note: `amount`, `currencyCode` and `orderId` are required during payment creation. Make sure to pass these fields when creating a client session, or if not yet available, when creating a payment.

        All fields provided on this request will take preference over any field on the `order` associated with the client session. E.g. if you pass `amount` on this request, it will override the `amount` on the `order` associated with the Client Session.
        Parameters that are not on this request will be fetched from previously created Client Session and merged. E.g. if you specify `customer.billingAddress` in Client Session and then pass `customer.emailAddress` data with this request, it will automatically merge the `customer` fields and use both `billingAddress` and `emailAddress` for later calculations.

      operationId: create_payment_payments_post
      parameters:
        - $ref: '#/components/parameters/IdempotencyHeader'
        - $ref: '#/components/parameters/ApiVersionHeader'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PaymentCreationAPIRequest'
        required: true
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaymentAPIResponse'
              example:
                id: kHdEw9EG
                date: '2021-02-21T15:36:16.367687'
                dateUpdated: '2021-02-21T15:36:17.133701'
                status: AUTHORIZED
                orderId: order-abc
                currencyCode: EUR
                amount: 42
                customerId: customer-123
                customer:
                  email: [email protected]
                cardTokenType: CARD_PAN
                paymentMethod:
                  paymentType: SUBSCRIPTION
                  paymentMethodToken: heNwnqaeRiqvY1UcslfQc3wxNjEzOTIxNjc4
                  isVaulted: true
                  authorizationType: FINAL
                  descriptor: 'Purchase: Socks'
                  analyticsId: VtkMDAxZW5isH0HsbbNxZ3lo
                  paymentMethodType: PAYMENT_CARD
                  paymentMethodData:
                    first6Digits: '411111'
                    last4Digits: '1111'
                    expirationMonth: '12'
                    expirationYear: '2030'
                    cardholderName: John Biggins
                    network: Visa
                    isNetworkTokenized: false
                    binData:
                      network: VISA
                      regionalRestriction: UNKNOWN
                      accountNumberType: UNKNOWN
                      accountFundingType: UNKNOWN
                      prepaidReloadableIndicator: NOT_APPLICABLE
                      productUsageType: UNKNOWN
                      productCode: VISA
                      productName: VISA
                processor:
                  name: STRIPE
                  processorMerchantId: acct_stripe_1234
                  amountCaptured: 0
                  amountRefunded: 0
                transactions:
                  - type: SALE
                    processorStatus: AUTHORIZED
                    processorName: STRIPE
                    processorMerchantId: acct_stripe_1234
                    processorTransactionId: 54c4eb5b3ef8a
                    cardTokenType: CARD_PAN
                metadata:
                  productId: 123
                  merchantId: a13bsd62s
                riskData:
                  fraudChecks:
                    source: FRAUD_PROVIDER
                    preAuthorizationResult: THREE_DS
                    postAuthorizationResult: ACCEPT
                  cvvCheck:
                    source: PROCESSOR
                    result: MATCHED
                  avsCheck:
                    source: PROCESSOR
                    result:
                      streetAddress: NOT_MATCHED
                      postalCode: NOT_VERIFIED
        '400':
          description: Error Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/400ErrorResponse'
              examples:
                GenericError:
                  value:
                    error:
                      errorId: PaymentError
                      description: The payment could not be created.
                      diagnosticsId: '1234567898'
                IdempotencyError:
                  value:
                    error:
                      errorId: TransactionRequestIdempotencyKeyAlreadyExists
                      description: >-
                        Transaction request already exists with idempotency key 'IDEMPOTENCY_KEY'.
                      paymentId: 6gHJtooK6
                      paymentStatus: SETTLED
                      diagnosticsId: '1234567898'
                      validationErrors: []
                MetadataContainsEmptyKey:
                  summary: Metadata field contains empty string key.
                  value:
                    error:
                      errorId: MetadataContainsEmptyKey
                      description: Metadata field contains empty string key.
                      recoverySuggestion: >-
                        Either remove empty string keys or provide non-empty string
                        instead.
                      diagnosticsId: '1234567898'
        '422':
          description: Error Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/422ErrorResponse'
              example:
                error:
                  errorId: RequestValidationError
                  description: Missing fields for payment.
                  recoverySuggestion: >-
                    When creating a payment `amount` must either be provided via the
                    Client Session or the Payment request.
                  diagnosticsId: '1234567898'
  /payments/{id}/authorize:
    post:
      tags:
        - Payments API
      summary: Authorize a payment
      description: |
        <p/>

        Manually authorize a payment using a provided processor. This is useful if you want to authorize a payment without a workflow action.
        The processor merchant ID must be provided which can be found on the [Integrations page](https://dashboard.primer.io/integrations).
        The processor name is optional but it must be provided if your account has multiple processors configured which share the same merchant IDs.
      operationId: authorize_payment_payments__id__authorize_post
      parameters:
        - required: true
          schema:
            title: Payment ID
            type: string
          name: id
          description: ID of the payment to authorize.
          in: path
        - $ref: '#/components/parameters/IdempotencyHeader'
        - $ref: '#/components/parameters/ApiVersionHeader'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PaymentAuthorizationAPIRequest'
            example:
              processor:
                processorMerchantId: acct_myprocessor_1234
        required: true
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaymentAPIResponse'
              example:
                id: kHdEw9EG
                date: '2021-02-21T15:36:16.367687'
                dateUpdated: '2021-02-21T15:36:17.133701'
                status: AUTHORIZED
                orderId: order-abc
                customerId: customer-123
                currencyCode: EUR
                amount: 42
                cardTokenType: CARD_PAN
                paymentMethod:
                  paymentType: SUBSCRIPTION
                  paymentMethodToken: heNwnqaeRiqvY1UcslfQc3wxNjEzOTIxNjc4
                  isVaulted: true
                  authorizationType: FINAL
                  descriptor: 'Purchase: Socks'
                  analyticsId: VtkMDAxZW5isH0HsbbNxZ3lo
                  paymentMethodType: PAYMENT_CARD
                  paymentMethodData:
                    first6Digits: '411111'
                    last4Digits: '1111'
                    expirationMonth: '12'
                    expirationYear: '2030'
                    cardholderName: John Biggins
                    network: Visa
                    isNetworkTokenized: false
                    binData:
                      network: VISA
                      regionalRestriction: UNKNOWN
                      accountNumberType: UNKNOWN
                      accountFundingType: UNKNOWN
                      prepaidReloadableIndicator: NOT_APPLICABLE
                      productUsageType: UNKNOWN
                      productCode: VISA
                      productName: VISA
                processor:
                  name: MYPROCESSOR
                  processorMerchantId: acct_myprocessor_1234
                  amountCaptured: 42
                  amountRefunded: 0
                customer:
                  email: [email protected]
                metadata:
                  productId: 123
                  merchantId: a13bsd62s
                transactions:
                  - type: SALE
                    processorStatus: AUTHORIZED
                    processorName: MYPROCESSOR
                    processorMerchantId: acct_myprocessor_1234
                    processorTransactionId: 54c4eb5b3ef8a
                    cardTokenType: CARD_PAN
                riskData:
                  fraudChecks:
                    source: FRAUD_PROVIDER
                    preAuthorizationResult: THREE_DS
                    postAuthorizationResult: ACCEPT
                  cvvCheck:
                    source: PROCESSOR
                    result: MATCHED
                  avsCheck:
                    source: PROCESSOR
                    result:
                      streetAddress: NOT_MATCHED
                      postalCode: NOT_VERIFIED
        '400':
          description: Error Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/400ErrorResponse'
              examples:
                PaymentAlreadyAuthorized:
                  value:
                    error:
                      errorId: PaymentAlreadyAuthorized
                      description: The payment has already been authorized
                      diagnosticsId: '1234567898'
                InvalidPaymentStatus:
                  value:
                    error:
                      errorId: InvalidPaymentStatus
                      description: A settled payment cannot be authorized
                      diagnosticsId: '1234567898'
                MerchantAccountNotFound:
                  value:
                    error:
                      errorId: MerchantAccountNotFound
                      description: The merchant account could not be found
                      diagnosticsId: '1234567898'
                MerchantAccountConflict:
                  value:
                    error:
                      errorId: MerchantAccountConflict
                      description: >-
                        More than one merchant account was found for the provided
                        processor merchant ID
                      diagnosticsId: '1234567898'
        '404':
          description: Payment not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/404ErrorResponse'
              example:
                error:
                  errorId: PaymentNotFoundError
                  description: The payment could not be found
                  diagnosticsId: '1234567898'
                  validationErrors: []
        '409':
          description: Idempotency key already exists
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/409ErrorResponse'
              example:
                error:
                  errorId: IdempotencyKeyAlreadyExists
                  description: >-
                    The idempotency key "1234567898" already exists for transaction
                  diagnosticsId: '1234567898'
        '422':
          description: Request failed validation
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/422ErrorResponse'
              example:
                error:
                  errorId: RequestValidationError
                  description: >-
                    We were unable to validate your request, please check your payload
                    against /docs/api
                  diagnosticsId: '1234567898'
                  validationErrors:
                    - model: PaymentAuthorizationAPIRequest
                      errors:
                        - path: $.processor.processorMerchantId
                          description: Value must be a valid string
  /payments/{id}/capture:
    post:
      tags:
        - Payments API
      summary: Capture a payment
      description: |
        <p/>

        If you have successfully authorized a payment, you can now
        fully capture, or partially capture funds from the authorized payment, depending
        on whether your selected payment processor supports it. The payment will
        be updated to `SETTLED` or `SETTLING`, depending on the payment method type.

        The payload sent in this capture request is completely optional. If you don't
        send a payload with the capture request, the full amount that was authorized
        will be sent for capture. Below are the available payload attributes, which
        give you more granular control when capturing funds, if you require it.
      operationId: capture_payment_payments__id__capture_post
      parameters:
        - required: true
          schema:
            title: Payment ID
            type: string
          name: id
          description: ID of the payment to capture.
          in: path
        - $ref: '#/components/parameters/IdempotencyHeader'
        - $ref: '#/components/parameters/ApiVersionHeader'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PaymentCaptureAPIRequest'
              title: Data
              default:
                final: true
            examples:
              Basic:
                value:
                  amount: 42
              Using Metadata:
                value:
                  amount: 42
                  metadata:
                    extraField: Text value
              Using Expand:
                value:
                  amount: 42
                  expand:
                    - transactions.events
              Final Capture:
                value:
                  amount: 42
                  final: true
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaymentAPIResponse'
              example:
                id: kHdEw9EG
                date: '2021-02-21T15:36:16.367687'
                dateUpdated: '2021-02-21T15:36:17.133701'
                status: SE

# --- truncated at 32 KB (211 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/primer/refs/heads/main/openapi/primer-payments-openapi.yml