API Integration

Overview

Sawfish Payment APIs are built in GraphQL (except generate tokens and refresh tokens endpoints).

To use the API integration, follow the User Flow Guide and refer to the API Reference.

The following information is our legacy guide for API documentation


Legacy Documentation

Authentication & Headers

Required Headers

  • To obtain your x-client-id, x-api-key please contact the Sawfish team.
  • These key-value pairs are required in specific requests to Sawfish’s RESTful and GraphQL APIs.
Header nameDescriptionRequiredExample
Content-typeRequest content typeapplication/json
AcceptExpected response formatapplication/json
x-client-idClient ID from App Integration settingsyour-client-id
x-jwt-tokenJWT token (expires after 10 minutes)your-api-token
x-api-keyAPI Keyyour-api-token

⚠️ JWT tokens expire after 10 minutes. Use the refresh token flow to obtain a new one.

Request Body Structure for GraphQL

{
  "query": "GraphQL query/mutation string",
  "variables": {
    "variable1": "value1",
    "variable2": "value2"
  }
}

Generate token

ℹ️ This is a REST API endpoint.

This generates an access token that is valid for 10 minutes. This endpoint should be called only once. After obtaining the refresh_token, use the /token/refresh-token API to get a new access token.

Endpoint: POST https://{{sawfish_domain}}/api/v2/accounting/token/generate-token

Headers:

  • x-client-id
  • x-api-key

Sample success response:

{
  "status": "SUCCESS",
  "data": {
    "token": "your_token",
    "refresh_token": "your_refresh_token",
    "expiration": 1691123100
  }
}

Sample error response:

// Error code can be 401 or 500.
[
  'status' => "ERROR",
  'message' => "Sample error message"
]

Refresh new token

ℹ️ This is a REST API endpoint.

Endpoint: POST https://{{sawfish_domain}}/api/v2/accounting/token/refresh-token

Header params:

  • x-client-id
  • x-api-key

Body params:

{
  "refresh_token": "your_refresh_token"
}

Sample success response:

{
  "status": "SUCCESS",
  "data": {
    "token": "your_token",
    "refresh_token": "your_refresh_token",
    "expiration": 1691123100
  }
}

Sample error response:

// Error code can be 401 or 500.
[
  'status' => "ERROR",
  'message' => "Sample error message"
]

Fetch Payment Gateway Fees

ℹ️ Amount fees is GST inclusive.

Purpose: Get list of fees calculations based on payment amount and card types.

GraphQL Query: paymentGatewayFees

query paymentGatewayFeesCalc($amount: Float) {
    paymentGatewayFeesCalc(amount: $amount) {
        {
            amount
            fees
            total
            card_location
            card_type
        }
    }
}

Response structure:

inteface PaymentGatewayFeesCalcResponse {
  {
    amount: float
    fees: float
    total: float
    card_location: string;
    card_type: string;
  }[]
}

Process Payment

Purpose: Processes payment via Sawfish platform. It will try to validate the credit card details before processing the payment. An error may be returned regarding invalid credit card to avoid processing payment.

GraphQL Mutation: processPaymentRequest

mutation processPaymentRequest($input: ProcessPaymentInput!) {
  processPaymentRequest(input: $input) {
    amount
    payment_gateway_fee
    paid_at
    status {
      name
    }
    uuid
  }
}

Example variables:

interface ProcessPaymentInput {
  credit_card: CreditCardInput!;
  amount: number!;
  fees: number!;
  contact: ContactInput!;
}

interface CreditCardInput {
  full_name: string!;
  number: string!;
  expiry_month: string!;
  expiry_year: string!;
  cvv: string!;
}

interface ContactInput {
  first_name: string!;
  last_name: string!;
  email: string!;
  description: string!;
  reference_no: string!;
  address_line1: string;
  city: string;
  state: string;
  zip: string;
  country: string;
  phone?: string;
}

Response structure:

{
  amount: number;
  payment_gateway_fee: number;
  paid_at: string;
  status: string;
  uuid: string;
}

Payment Webhook

Purpose: After a payment is processed, the initial status simply confirms that the payment request has been initiated. Credit card transactions may take some time to fully process. To track the final status—whether the payment succeeds or fails—it is essential to register a webhook URL (contact the Sawfish team to configure this) where Sawfish can send status updates to your system.

Sample of webhook URL: https://{{your_domain}}/webhook/payments

When the webhook is triggered, Sawfish will send a response containing the payment payload along with HTTP headers that include the webhook signing key and client ID. These headers are critical for security. We strongly recommend validating all incoming webhook requests by verifying the header values against your stored keys before processing the data.

Payload structure:

{
  amount: number;
  payment_gateway_fee: number;
  paid_at: string;
  status: string;
  uuid: string;
}

Error Handling

# Errors

{
  "errors": [
    {
      "message": "Error description",
      "extensions": {
        "reason": "ERROR_CODE"
      }
    }
  ]
}

# Sample validation Errors

{
    "errors": [
        {
            "message": "Validation failed for the field [processPaymentRequest].",
            "extensions": {
                "validation": {
                    "input.contact": [
                        "Contact information is required."
                    ],
                    "input.credit_card.expiry_year": [
                        "Expiry year cannot be in the past."
                    ]
                },
                "category": "validation"
            }
        }
    ]
}

Optional: Credit card validation (Work in progress)

Purpose: This is an optional endpoint used to validate credit card details.

GraphQL Mutation: creditCardValidation