Pay1st Gateway API

The Pay1st Gateway API lets partners authenticate, list local payment methods per country, create signed payment requests, query payment status, and issue refunds across 120+ African payment methods, with Carry1st acting as Merchant of Record.

Documentation

Specifications

Other Resources

OpenAPI Specification

carry1st-pay1st-gateway-openapi.yml Raw ↑
openapi: 3.1.0
info:
  title: Pay1st Gateway API
  version: '4.0'
  description: >-
    The Pay1st Gateway API from Carry1st enables digital-content and mobile-game
    partners to accept payments across Africa via 120+ local payment methods in
    South Africa, Nigeria, Kenya, Egypt, Morocco, and Ghana. Partners authenticate
    with an API Key/Secret to obtain a short-lived Access Token, sign each mutating
    request with an HMAC-SHA256 signature, create payment requests, query payment
    status, and issue refunds. Carry1st acts as Merchant of Record, managing
    compliance, tax, FX, and risk. This OpenAPI was DERIVED by API Evangelist from
    the public Pay1st reference documentation (endpoint paths, headers, request and
    response fields, and examples verbatim from the docs); it is not a
    provider-published spec.
  contact:
    name: Pay1st Developer Documentation
    url: https://pay1st-docs.carry1st.com/
  x-apievangelist-derived-from: https://pay1st-docs.carry1st.com/
servers:
  - url: https://api-gateway.carry1st.com
    description: Production
  - url: https://api-gateway.platform.stage.carry1st.com
    description: Sandbox / Staging
tags:
  - name: Authentication
    description: Obtain and refresh access tokens for Gateway API requests.
  - name: Payment Methods
    description: Discover the local payment methods available per country.
  - name: Payments
    description: Create payment requests and query their status.
  - name: Refunds
    description: Request refunds against processed transactions.
paths:
  /api/pay1st/auth/token:
    post:
      operationId: generateAccessToken
      tags: [Authentication]
      summary: Generate Access Token
      description: >-
        Authenticate with your API Key and API Secret (HTTP Basic) to obtain an
        Access Token and Refresh Token used for all subsequent Gateway requests.
      security:
        - basicAuth: []
      requestBody:
        required: true
        content:
          application/vnd.carry1st.payments.partnerauthentication+json:
            schema:
              $ref: '#/components/schemas/TokenRequest'
            example:
              role: API_USER
      responses:
        '200':
          description: Access and refresh tokens issued.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TokenResponse'
        '400': { $ref: '#/components/responses/BadRequest' }
        '401': { $ref: '#/components/responses/Unauthorized' }
        '403': { $ref: '#/components/responses/Forbidden' }
        '429': { $ref: '#/components/responses/TooManyRequests' }
  /api/pay1st/auth/refresh:
    post:
      operationId: refreshAccessToken
      tags: [Authentication]
      summary: Generate Refresh Token
      description: Extend the lifetime of an Access Token using the Refresh Token.
      security:
        - basicAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TokenResponse'
      responses:
        '200':
          description: A new Access Token has been issued.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TokenResponse'
        '400': { $ref: '#/components/responses/BadRequest' }
        '401': { $ref: '#/components/responses/Unauthorized' }
  /api/pay1st/payments/methods:
    get:
      operationId: listPaymentMethods
      tags: [Payment Methods]
      summary: List Payment Methods
      description: List the supported local payment methods for a given country.
      security:
        - accessToken: []
      parameters:
        - name: countryCode
          in: query
          required: true
          description: ISO-2 country code, e.g. ZA, NG, KE, EG, MA, GH.
          schema:
            type: string
            example: NG
      responses:
        '200':
          description: A list of available payment methods.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/PaymentMethod'
        '401': { $ref: '#/components/responses/Unauthorized' }
        '429': { $ref: '#/components/responses/TooManyRequests' }
  /api/pay1st/payments/create:
    post:
      operationId: createPaymentRequest
      tags: [Payments]
      summary: Create Payment Request
      description: >-
        Create a payment request before a payment is made. Requires a valid Access
        Token plus an X-SIGNATURE (hex HMAC-SHA256) and X-TIMESTAMP header.
      security:
        - accessToken: []
      parameters:
        - $ref: '#/components/parameters/XSignature'
        - $ref: '#/components/parameters/XTimestamp'
      requestBody:
        required: true
        content:
          application/vnd.carry1st.payments.payment+json:
            schema:
              $ref: '#/components/schemas/CreatePaymentRequest'
            example:
              countryCode: NG
              currencyCode: NGN
              amount: 100
              partnerReference: 1119bf84-dc97-4be9-aa67-ec27d7003f07
              products:
                - title: 10Credits
                  sku: '12345'
                  price: 100
                  quantity: 1
                  currencyCode: NGN
              metadata:
                - key: customerId
                  value: '1'
      responses:
        '201':
          description: Payment request created.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaymentResponse'
              example:
                reference: C-113976984708914-P
                partnerReference: e27b3b79-5ab3-4c1b-806f-1428c08d8637
                countryCode: NG
                currencyCode: NGN
                amount: 100
                status: NEW
        '400': { $ref: '#/components/responses/BadRequest' }
        '401': { $ref: '#/components/responses/Unauthorized' }
  /api/pay1st/payments:
    get:
      operationId: queryPaymentStatus
      tags: [Payments]
      summary: Query Payment Status
      description: Query the current status of a payment using its Pay1st reference.
      security:
        - accessToken: []
      parameters:
        - name: reference
          in: query
          required: true
          description: The Pay1st reference returned by createPaymentRequest.
          schema:
            type: string
            example: C-142710055596150-P
      responses:
        '200':
          description: The payment and its current status.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaymentDetail'
        '400': { $ref: '#/components/responses/BadRequest' }
        '401': { $ref: '#/components/responses/Unauthorized' }
        '403': { $ref: '#/components/responses/Forbidden' }
        '429': { $ref: '#/components/responses/TooManyRequests' }
  /api/pay1st/transactions/refunds/create:
    post:
      operationId: createRefundRequest
      tags: [Refunds]
      summary: Refund Request
      description: >-
        Request a refund against a processed transaction. If no amount is supplied
        a full refund is processed. Requires Access Token plus X-SIGNATURE and
        X-TIMESTAMP. NOTE: this API is in beta.
      security:
        - accessToken: []
      parameters:
        - $ref: '#/components/parameters/XSignature'
        - $ref: '#/components/parameters/XTimestamp'
      requestBody:
        required: true
        content:
          application/vnd.carry1st.payments.refund+json:
            schema:
              $ref: '#/components/schemas/RefundRequest'
            example:
              transactionReference: C-12345-T
              partnerRefundReference: P-12345
              amount: 50.00
              reason: Customer requested refund
      responses:
        '201':
          description: Refund request accepted.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RefundResponse'
        '400': { $ref: '#/components/responses/BadRequest' }
        '401': { $ref: '#/components/responses/Unauthorized' }
components:
  securitySchemes:
    basicAuth:
      type: http
      scheme: basic
      description: Base64(API_KEY:API_SECRET) used only on the auth/token and auth/refresh endpoints.
    accessToken:
      type: apiKey
      in: header
      name: AccessToken
      description: 'Bearer <AccessToken> issued by generateAccessToken; required on all Gateway API requests.'
  parameters:
    XSignature:
      name: X-SIGNATURE
      in: header
      required: true
      description: Hex-encoded HMAC-SHA256 signature of the timestamp + request JSON.
      schema:
        type: string
    XTimestamp:
      name: X-TIMESTAMP
      in: header
      required: true
      description: Current time in ISO-8601, identical to the timestamp used to build the signature.
      schema:
        type: string
        format: date-time
  responses:
    BadRequest:
      description: Bad Request - check the payload, params, or signature/timestamp headers.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Unauthorized:
      description: Unauthorized - check the API Key/Secret or Access Token.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Forbidden:
      description: Forbidden - the credentials lack permission for this resource.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    TooManyRequests:
      description: Too Many Requests - the partner is being rate limited.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  schemas:
    TokenRequest:
      type: object
      required: [role]
      properties:
        role:
          type: string
          enum: [API_USER]
          description: Must be set to API_USER.
    TokenResponse:
      type: object
      properties:
        role:
          type: string
          example: API_USER
        accessToken:
          type: string
        refreshToken:
          type: string
    PaymentMethod:
      type: object
      properties:
        channelId:
          type: integer
          example: 108
        channelName:
          type: string
          example: Opay Wallet
        countryCode:
          type: string
          example: NG
        currencyCode:
          type: string
          example: NGN
    Product:
      type: object
      properties:
        currencyCode:
          type: string
        price:
          type: number
        quantity:
          type: integer
        sku:
          type: string
        title:
          type: string
    Metadata:
      type: object
      properties:
        key:
          type: string
        value:
          type: string
    CreatePaymentRequest:
      type: object
      required: [amount, countryCode, currencyCode, partnerReference, products, metadata]
      properties:
        amount:
          type: number
          description: The amount to pay.
        countryCode:
          type: string
          description: ISO-2 country code, e.g. ZA.
        currencyCode:
          type: string
        partnerReference:
          type: string
          description: Unique partner reference for reconciliation; must be unique for the lifetime of the integration.
        callbackSuccessUrl:
          type: string
        callbackFailureUrl:
          type: string
        callbackPendingUrl:
          type: string
        callbackCancelUrl:
          type: string
        webhookUrl:
          type: string
        products:
          type: array
          items:
            $ref: '#/components/schemas/Product'
        metadata:
          type: array
          items:
            $ref: '#/components/schemas/Metadata'
    PaymentResponse:
      type: object
      properties:
        reference:
          type: string
        partnerReference:
          type: string
        countryCode:
          type: string
        currencyCode:
          type: string
        amount:
          type: number
        status:
          $ref: '#/components/schemas/PaymentStatus'
    PaymentDetail:
      allOf:
        - $ref: '#/components/schemas/PaymentResponse'
        - type: object
          properties:
            channelId:
              type: integer
            channelName:
              type: string
            partnerSettings:
              type: object
              properties:
                partnerId:
                  type: integer
                webhookUrl:
                  type: string
                successCallbackUrl:
                  type: string
                failureCallbackUrl:
                  type: string
                pendingCallbackUrl:
                  type: string
                cancelCallbackUrl:
                  type: string
            products:
              type: array
              items:
                $ref: '#/components/schemas/Product'
            metadata:
              type: array
              items:
                $ref: '#/components/schemas/Metadata'
    PaymentStatus:
      type: string
      description: Payment lifecycle status.
      enum: [NEW, PENDING, SUCCESSFUL, FAILED, CANCELLED, ABANDONED]
    RefundRequest:
      type: object
      required: [transactionReference]
      properties:
        transactionReference:
          type: string
          description: The Pay1st identifier obtained from createPaymentRequest.
        partnerRefundReference:
          type: string
        amount:
          type: number
          description: If omitted, a full refund is processed.
        reason:
          type: string
        refundWebhookUrl:
          type: string
    RefundResponse:
      type: object
      properties:
        refundReference:
          type: string
        transactionReference:
          type: string
        partnerReference:
          type: string
        partnerRefundReference:
          type: string
        amount:
          type: number
        currencyCode:
          type: string
        status:
          type: string
          enum: [PENDING, PROCESSING, SUCCESSFUL, FAILED, REJECTED]
        handlingType:
          type: string
          enum: [PSP_API, PSP_MANUAL, NO_REFUND]
        fullRefund:
          type: boolean
        reason:
          type: string
        createdDate:
          type: string
          format: date-time
        lastModifiedDate:
          type: string
          format: date-time
    Error:
      type: object
      description: Standard Pay1st error envelope.
      properties:
        errorMessage:
          type: string
          description: A message detailing the error that occurred.
        errorCode:
          type: string
          description: A code to identify the error source.
        sessionId:
          type: string
          description: Session identifier to share with the Pay1st Implementation Manager for troubleshooting.