API Reference

Introduction

The Subscriptions API allows merchants to manage subscription lifecycles — creating customers, memberships, and sessions — through a secure REST interface. Built for seamless integration with Paytiko subscription services.


Prerequisites

Before integrating with the Paytiko Subscriptions API, ensure that the following requirements are met:

  • You must have valid API credentials (issued by Paytiko).

  • All communication must be over HTTPS only.

  • You must know your processorKey, and be able to retrieve and persist the customerKey and membershipKey via the API.

  • Your backend must support JWT-based authentication for including the Authorization: Bearer <token> header.

  • You should implement secure storage of credentials, tokens, and keys (never expose secrets to the client/browser).

  • You must configure and expose a publicly accessible webhook endpoint to receive subscription and payment event notifications from Paytiko.

  • You should handle idempotency when processing webhook events (e.g., avoid duplicate handling).

  • Ensure your system’s time zone and clocks are synchronized (UTC recommended), since subscription cycles and endDate validation are time-sensitive.

  • Your customer and product data should meet validation requirements (ISO country codes, valid email/phone formats, well-formed URIs).

  • You must implement error handling for API responses (HTTP 4xx, 5xx) to gracefully manage failed requests.

  • For checkout and portal sessions, ensure you can redirect customers to the hosted Paytiko pages and handle return URLs.


Best Practices

To build a robust and reliable integration, consider the following recommendations:

  • Token Management:

    • Refresh tokens before they expire (tokens are short-lived).

    • Do not hardcode tokens; request them dynamically when needed.

  • Webhook Reliability:

    • Treat all webhook requests as asynchronous events.

    • Always return HTTP 200 OK after successful processing.

    • Implement a retry strategy: if your system fails temporarily, Paytiko may resend webhooks — handle duplicates safely.

  • Security:

    • Verify incoming webhook requests (e.g., by checking signatures or IP allowlists if provided by Paytiko).

    • Use HTTPS everywhere; never log sensitive data such as passwords or full card numbers.

  • Data Integrity:

    • Validate incoming fields against your business logic (currency, amounts, interval counts).

    • Store customerKey and membershipKey in your database to link Paytiko records with your own user accounts.

  • Error Handling:

    • Retry failed API calls using exponential backoff.

    • Log both request and response data (excluding sensitive information) for debugging and reconciliation.


Technical Flow

This section describes the end-to-end lifecycle of how a subscription is created, purchased, and billed using the Paytiko Subscriptions API. The process covers authentication, customer creation, checkout, payment confirmation, invoicing, and recurring billing.

  1. Customer requests a subscription The flow begins when a customer chooses a subscription plan on the merchant’s website or application.

  2. Merchant authenticates The merchant uses its Paytiko-issued API credentials to obtain a secure access token. This token is required for all subsequent API requests.

  3. Merchant creates a customer Using the customer’s details (name, email, phone, billing info), the merchant calls Paytiko to register a new customer. Paytiko returns a unique customerKey, which the merchant stores in its own database.

  4. Merchant creates a membership The merchant associates the customer with a subscription plan by creating a membership. This defines pricing, billing intervals, and product details. Paytiko returns a membershipKey.

  5. Merchant initiates a checkout session To complete the purchase, the merchant creates a checkout session linked to the customerKey and membershipKey. Paytiko responds with a redirectUrl, and the merchant redirects the customer to the hosted checkout page.

  6. Customer confirms identity and pays The customer interacts with Paytiko’s secure checkout to confirm their identity and complete payment.

  7. Paytiko notifies the merchant Upon successful payment (or failure), Paytiko sends a webhook notification to the merchant. At the same time, an invoice or receipt is emailed directly to the customer.

  8. Recurring billing cycles run automatically On each billing cycle, Paytiko processes the recurring charge. The merchant receives webhook notifications with charge results, while the customer receives invoices by email.

Flow Diagram

The following diagram illustrates the process:

Cick the image to expand..
Cick the image to expand..

Endpoints

This section provides detailed documentation for all available Paytiko Subscriptions API endpoints. Each endpoint description includes:

  • Method & Path – The HTTP method (e.g., POST, GET) and full URI.

  • Overview – A short description of the purpose of the endpoint.

  • Headers – Required and optional HTTP headers.

  • Request Body – JSON model with all fields and validation rules.

  • Response – Example success and error responses.

All requests must be authenticated using a JWT bearer token obtained via the Authentication endpoint.


Try It Yourself — Postman Collection

To get started quickly, you can import our Postman Collection, which contains ready-to-use requests for all endpoints:

  • Preconfigured with request URLs and headers

  • Includes example payloads for authentication, customer creation, membership creation, and checkout

  • Helps you test the flow end-to-end before integrating into your system

When you import the Paytiko Integration: Subscriptions API Postman collection, it comes with a Default Environment that contains all necessary variables (such as API host, processor key & user credentials). The list of avaliable usage options you can find below.

  1. Quick Start with Demo If you just want to explore and run sample requests with our global demo account, no configuration is required.

    • The collection is already preconfigured with demo values in the Default Environment.

    • You can immediately send requests and test the API end-to-end

  2. Configure your own Organization

    To test requests against your own organization:

    1. Open the Default Environment in Postman.

    2. Replace the demo values ( UserName, Password, ProcessorKey, ApiHost, etc. ) with the credentials and keys provided by our team.

    3. Click Save to update the environment.

    4. All collection requests will now run against your account and your data.


Authentication

POST /api/subscriptions/v1/auth

The authentication endpoint is used to obtain a JWT bearer token. This token is required in the Authorization header for all other API requests.

Request Headers

Name
Value
Required

Content-Type

application/json

Request Body

Name
Type
Description
Required

userName

string

User name

password

string

Password

Response


Customers

Create Customer

POST /api/subscriptions/v1/customer

This endpoint registers a new customer in the subscription system. The customer is the entity that owns memberships, billing details, and sessions.

Use case: When a new end user signs up, you must create their customer profile before adding memberships.

Customer uniqueness A customer is uniquely identified by their email address within the scope of a single merchant.

circle-exclamation

This request is idempotent

Request Headers

Name
Value
Required

Content-Type

application/json

Authorization

Bearer <token>

Request Body

Name
Type
Required
Description

processorKey

string (UUID)

Processor identifier.

Must be a non-empty GUID (canonical UUID).

firstName

string

Customer first name.

Must match ^\p{L}+(?:[ -]\p{L}+)*$ → letters only (Unicode), hyphens and spaces.

lastName

string

Customer last name.

Must match ^\p{L}+(?:[ -]\p{L}+)*$ → letters only (Unicode), hyphens and spaces.

email

string

Customer email.

Must pass server email validation, standard name@domain.tld.

phone

string

Customer phone number.

Must match the E.164 international format (regex pattern is ^+[1-9]\d{7,14}$).

  • Must begin with a “+” sign followed by the country code and subscriber number

  • Cannot start with 0 after the +

  • Must be between 8 and 15 digits total (excluding the +)

  • No spaces, hyphens, or special characters allowed.

countryCode

string

Country (ISO-3166-1 alpha-2).

Exactly 2 letters and must be recognized by the server’s country list; case-insensitive (use uppercase like US, PL).

address1

string

Street address line 1.

Optional; no additional validation in current model.

address2

string

Apartment/Suite.

Optional; no additional validation.

city

string

City/Locality.

Optional; no additional validation.

state

string

State/Region/Province.

Optional; no additional validation.

zipCode

string

Postal/ZIP code.

Optional; no additional validation.

taxIds

array

Business tax identifiers. Present in cURL examples but not in the provided C# model/validator.

Each item is typically { "type": string, "value": string }. No explicit server-side validation rules provided in the shared code.

chevron-rightRequest Body Sample hashtag

Response


Get Customer by Key

GET /api/subscriptions/v1/customer/{customerKey}

Retrieves full details of a previously created customer.

Use case: Fetch customer information to display in your UI or confirm that a customer exists before assigning memberships.

Headers

Name
Value
Required

Authorization

Bearer <token>

Response


Update Customer Phone

PUT /api/subscriptions/v1/customer/phone

This endpoint updates the phone number of an existing subscription customer. The customer remains the same entity that owns memberships, billing details, and sessions — only the phone contact information is modified.

Use case: When a customer changes their phone number — for example, during account update flows or to maintain up-to-date contact information for billing or 3D Secure challenges — the merchant can update it programmatically using this endpoint.

Request Headers

Name
Value
Required

Content-Type

application/json

Authorization

Bearer <token>

Request Body

Name
Type
Required
Description

customerKey

string

Customer identifier.

Must start with prefix cstmr_. Used to link the membership to an existing customer.

phone

string

Customer phone number.

Must match the E.164 international format (regex pattern is ^+[1-9]\d{7,14}$).

  • Must begin with a “+” sign followed by the country code and subscriber number

  • Cannot start with 0 after the +

  • Must be between 8 and 15 digits total (excluding the +)

  • No spaces, hyphens, or special characters allowed.

chevron-rightRequest Body Sample hashtag

Response


Memberships

Create Membership

POST /api/subscriptions/v1/membership

This endpoint registers a new membership for a customer. A membership defines the subscription relationship, including product details, pricing, and billing cycle.

Use case: When a customer purchases a subscription plan, the merchant must create a membership linked to that customer, ensuring the subscription can be billed and managed.

Membership uniqueness A membership is uniquely identified by its orderId (external order identifier) within the scope of a single customer.

circle-exclamation

This request is idempotent

Request Headers

Name
Value
Required

Content-Type

application/json

Authorization

Bearer <token>

Request Body

Name
Type
Required
Description & Validation Rules

customerKey

string

Customer identifier.

Must start with prefix cstmr_. Used to link the membership to an existing customer.

subscriptionName

string

Human-readable plan name.

Must be non-empty. Shown in invoices/portal and useful for your internal reporting. Has a maximum length of 250 characters.

endDate

string

Optional subscription end date.

  • Must be in UTC ISO-8601 format (e.g. YYYY-MM-DDTHH:mm:ss).

  • Must be at least 1 hour ahead of the current UTC time.

  • If provided, no new billing cycles will start after this moment.

  • If not provided, the subscription will be infinite and continue to run until it is explicitly cancelled.

Valid examples:

  • 2025-09-01T12:00:00 → valid, 1 September 2025 at 12:00 UTC

  • 2025-08-21T19:45:00 → valid if current UTC < 18:45 UTC (at least +1h ahead)

productInfo

object

Product details.

See productInfo.

pricingInfo

object

Pricing details.

See pricingInfo.

billingCycle

object

Recurrence definition.

See billingCycle.

webhookUrl

string

Callback for lifecycle events.

Must be a well-formed absolute URL (HTTPS only).

Paytiko posts events like payment success/failure, subscription status changes, etc.

Your endpoint must return 2xx on success and be idempotent.

metadata

string

Merchant metadata.

Optional merchant-defined free-form string used to attach custom identifiers or correlation data to the subscription.

chargeEmitterQueue

string

Optional test/seed events.

If provided, cannot be an empty array. Each item must have transactionStatus Success or a negative enum value (per server).

Intended for test mode and QA scenarios.

See chargeEmitterQueue.

productInfo

Name
Type
Required
Description & Validation Rules

orderId

string

External order ID from your system.

Required to be unique to prevent accidental duplication.

description

string

Product description.

Optional, free-text product/order description (shown in UIs/invoices if supported).

pricingInfo

Name
Type
Required
Description & Validation Rules

currency

string

Currency code. Must be a 3-letter ISO 4217 code (e.g., USD, EUR).

totalAmount

string

Total subscription amount. Must be greater than 0.

If pricePerUnit and quantity are provided, then: totalAmount = pricePerUnit × quantity.

pricePerUnit

number

Price per unit.

Must be greater than 0 if provided. If provided together with quantity, their multiplication must equal totalAmount.

quantity

integer

Quantity of units.

Must be greater than 0 if provided. If provided together with pricePerUnit, their multiplication must equal totalAmount.

billingCycle

Name
Type
Required
Description & Validation Rules

intervalType

string

Billing interval.

Defines the base recurrence unit.

Must be one of: Daily, Weekly, Monthly, Annually.

intervalCount

integer

Interval multiplier.

Optional. Defines how many intervalType units between charges. Must be an integer ≥1 if provided. If not provided, defaults to 1.

Examples: intervalType=Weekly, intervalCount=2 → every 2

intervalType=Monthly, intervalCount=3 → every 3 months (quarterly)

circle-check

Monthly Billing Date Edge-Cases are Safely-Handled

chargeEmitterQueue[]

Name
Type
Required
Description & Validation Rules

transactionStatus

string

Transaction status filter.

Must be either:

  • Success → charge is processed successfully.

  • Rejected → charge is simulated as failed.

description

string

Error message returned when transactionStatus is Rejected.

Defaults to "Insufficient funds." if not provided.

When testing subscriptions in sandbox/test mode, the payment gateway normally supports only success-resulting test cards. That means all recurring charges would succeed by default.

To simulate real-world billing conditions (e.g., declines, retries, eventual success), you can provide a chargeEmitterQueue — an array that defines the outcome of each scheduled charge.

How it works

  • Each item in the array represents the result of the next charge attempt in sequence.

  • Allowed values are:

    • success → charge is processed successfully.

    • rejected → charge fails with a simulated decline.

  • Once all items in the array are consumed, the emitter stops and all subsequent charges default to success (unless you provide a longer array).

  • This applies only to recurring charges triggered by billing cycles.

  • The initial checkout payment is not affected by chargeEmitter (it always follows test card rules).

Expanation

  • 1st chargesuccess → The first billing cycle succeeds.

  • 2nd chargerejected → The next billing attempt is rejected.

  • 3rd chargerejected → Another failure is simulated.

  • 4th chargerejected → Third consecutive failure.

  • 5th chargesuccess → Billing finally succeeds again.

Rules

  • The queue defines charge behavior only (not the initial checkout payment).

  • If the queue has fewer items than the number of cycles, all remaining charges default to success.

  • If no chargeEmitter is provided, all charges default to success.

circle-info

Key points to remember

  • If chargeEmitterQueue is not provided, all charges are assumed successful.

  • You can use this feature to test retry logic, dunning flows, and webhook handling without needing special test cards.

  • Make sure your webhook implementation is idempotent, since rejected charges will trigger failure events you may want to retry.

chevron-rightRequest Body Samplehashtag

Response

Update Membership

PUT api/subscriptions/v1/membership

This endpoint updates existing membership for a customer. A membership defines the subscription relationship, including product details, pricing, and billing cycle.

We use a proration mechanism, so it means when pricePerUnit / quantity / intervalType / intervalCount is changed, we calculate amount that customer will be charged for. And only after proration charge membership will be updated. There is also can be a case, when proration amount will be negative, in such situation we will save this amount as a credits for next billing period charges. And when next billling cycle is comes and customer is have credits on his account than we will use them as discount, or if credit amount is so big we can even pay whole membership just with credits.

Request Headers

Name
Value
Required

Content-Type

application/json

Authorization

Bearer <token>

Request Body

Name
Type
Required
Description & Validation Rules

membershipKey

string

Membership identifier.

Must start with prefix mmbrshp_. Used to link the membership to an existing customer.

name

string

Human-readable plan name.

Must be non-empty. Shown in invoices/portal and useful for your internal reporting. Has a maximum length of 250 characters.

endDate

string

Optional subscription end date.

  • Must be in UTC ISO-8601 format (e.g. YYYY-MM-DDTHH:mm:ss).

  • Must be at least 1 hour ahead of the current UTC time.

  • If provided, no new billing cycles will start after this moment.

  • If not provided, the subscription will be infinite and continue to run until it is explicitly cancelled.

Valid examples:

  • 2025-09-01T12:00:00 → valid, 1 September 2025 at 12:00 UTC

  • 2025-08-21T19:45:00 → valid if current UTC < 18:45 UTC (at least +1h ahead)

pricePerUnit

object

Price per unit.

Must be greater than 0 if provided.

quantity

object

Quantity of units.

Must be greater than 0 if provided.

intervalType

object

Billing interval.

Defines the base recurrence unit.

Must be one of: Daily, Weekly, Monthly, Annually.

intervalCount

string

Interval multiplier.

Optional. Defines how many intervalType units between charges. Must be an integer ≥1 if provided. If not provided, defaults to 1.

Examples: intervalType=Weekly, intervalCount=2 → every 2

intervalType=Monthly, intervalCount=3 → every 3 months (quarterly)

returnToWebsiteLink

string

URL where customer should be redirected to after update.

Must be a well-formed absolute URL (HTTPS only).

metadata

string

Metadata string.

Optional merchant-defined free-form string used to attach custom identifiers or correlation data to the subscription.

chevron-rightRequest Body Samplehashtag

Response

Get Membership by Key

GET /api/subscriptions/v1/membership/{membershipKey}

Retrieves the full details of a previously created membership.

Use cases:

  • Fetch membership information to display in your UI (e.g., plan details, pricing, status).

  • Verify that a membership exists and check its current state (active, cancelled, expired) before performing further actions.

Request Headers

Name
Value
Required

Authorization

Bearer <token>

Response


Cancel Membership

POST /api/subscriptions/v1/membership/cancel/{membershipKey}

Cancels an active membership immediately. After cancellation:

  • No new billing cycles will be started.

  • Any open invoices (not yet finalized/paid) will be automatically transitioned to status Void.

  • Already paid or failed invoices remain unchanged.

Use cases

  • Let customers stop their subscription through your UI (e.g., “Cancel Subscription” button).

  • Programmatically end a trial or paid membership when business rules require.

  • Safely retry cancel calls without risk of duplication or errors.

Request Headers

Name
Value
Required

Authorization

Bearer <token>

Response

UI Sessions

Create Checkout Session

POST /api/subscriptions/v1/checkout/session

Creates a hosted checkout session for a specific customer and membership. It returns a redirect URL where the customer completes identity confirmation and payment.

How it works

  1. Your backend calls this endpoint with a valid customerKey and membershipKey.

  2. The API returns checkoutRedirectUrl.

  3. You redirect the customer’s browser to that URL.

  4. The customer completes checkout on Paytiko’s hosted page.

  5. Your system is notified via webhooks configured on the membership (e.g., payment succeeded/failed), and the customer receives an invoice email.

Use cases

  • Start the initial payment for a newly created membership.

  • Re-issue a checkout when a previous session expired.

  • Provide a pay now link from your app or email.

Request Headers

Name
Value
Required

Content-Type

application/json

Authorization

Bearer <token>

Request Body

Name
Type
Required
Description

customerKey

string

Customer identifier.

Must start with cstmr_.

membershipKey

string

Membership identifier.

Must start with mmbrshp_.

returnToWebsiteLink

string (URL)

Optional absolute return URL. A full URL where the customer is redirected after leaving the portal. Must be a valid absolute URL (e.g., https://example.com/return).

chevron-rightRequest Body Sample hashtag

Response


Create Portal Session

POST /api/subscriptions/v1/checkout/session

Creates a customer portal session URL. The portal is a hosted, self-service page where customers can view and manage their subscriptions (e.g., see plan details, invoices, update payment method—exact features depend on your configuration).

How it works

  1. Your backend calls this endpoint with the customer’s key.

  2. The API returns portalRedirectUrl.

  3. You redirect or link the customer to this URL to self-manage their billing profile.

Common use cases

  • Provide a “Manage subscription” link in your app.

  • Let customers view invoices or update payment details without building UI yourself.

  • Offer a self-service experience that reduces support workload.

Request Headers

Name
Value
Required

Content-Type

application/json

Authorization

Bearer <token>

Request Body

Name
Type
Required
Description

customerKey

string

Customer identifier.

Must start with cstmr_.

returnToWebsiteLink

string (URL)

Optional absolute return URL. A full URL where the customer is redirected after leaving the portal. Must be a valid absolute URL (e.g., https://example.com/return).

chevron-rightRequest Body Sample hashtag

Response


Webhooks

Overview

Paytiko sends webhooks to notify your system about important subscription events. There are three categories of webhook events:

  1. Transaction status updates — covers payments, refunds, charge attempts, etc.

    • In the webhook payload, the Action field will be set to:

    • Full reference for transaction webhooks can be found here.

  2. Membership status change — covers subscription lifecycle changes (e.g., activation, past due, cancellation).

    • In the webhook payload, the Action field will be set to:

    • Detailed documentation for membership webhooks is provided below in this section.

  3. Membership updates — sent when membership was updated.

    • In the webhook payload, the Action field will be set to:

    • Detailed documentation for membership webhooks is provided below in this section.


Delivery & Retries

Paytiko attempts to deliver each webhook event by sending an HTTP POST request to the merchant’s configured webhookUrl.

  • If your endpoint responds with an HTTP 2xx status code, the delivery is considered successful.

  • If your endpoint responds with a non-2xx status (e.g., 4xx, 5xx) or times out, the system will retry delivery.

Retry policy

  • Each webhook delivery has 1 initial attempt plus up to 6 retry attempts (7 attempts total).

  • A custom backoff schedule is applied:

    • The initial attempt is sent immediately.

    • The first retry is delayed by 5 minutes.

    • The second retry is delayed by 30 minutes.

    • Each subsequent retry doubles the delay (1 hour, 2 hours, 4 hours, 8 hours).

    Attempt #1 — Initial — Immediate Attempt #2 — Retry #1 — 5 minutes Attempt #3 — Retry #2 — 30 minutes Attempt #4 — Retry #3 — 1 hour Attempt #5 — Retry #4 — 2 hours Attempt #6 — Retry #5 — 4 hours Attempt #7 — Retry #6 — 8 hours

  • If all retry attempts fail, the event is marked as undeliverable and no further retries will be attempted.

  • All retry scheduling is based on UTC time, ensuring consistent behavior across time zones and daylight saving changes.

Best practices

  • Always return a 2xx response as quickly as possible — queue the work internally if needed.

  • Log incoming ActionId and Membership.Key values so you can reconcile missed events if a retry sequence is exhausted.

  • Keep your webhook endpoint highly available and resilient to ensure timely state synchronization.

Membership Status Change Webhook

What is it? A webhook sent whenever a membership (subscription) changes status. The payload includes the updated membership object and recent invoices for context.

How it works

  • Your webhookUrl (set during Create Membership) receives an HTTP POST with JSON.

  • The Status field in the payload reflects the new, updated subscription status.

  • You should update your local records and trigger any downstream logic (access enable/disable, emails, etc.).

Possible membership statuses

  • IncompleteExpired

  • Active

  • PastDue

  • Unpaid

  • Canceled

  • Completed

Statuses overview you can find here.

Only the status changes between events; the rest of the schema remains the same.

chevron-rightWebhook Payload Structure Samplehashtag
circle-info

Payload Handling Recommendations

  • Respond with 2xx quickly. Process heavy work asynchronously.

  • Idempotency: use ActionId (or your own event ID map) to ignore duplicates.

  • Security: verify authenticity (e.g., shared secret/signature) if your integration provides one.

  • Audit: log Action, ActionId, Membership.Key, Membership.Status, and IssuedAt.

  • State sync: treat webhook as source of truth for membership state changes and update your DB accordingly.


Membership Updated Webhook

What is it?

A webhook sent whenever an existing membership (subscription) is updated, meaning one or more of its key properties (e.g. name, price, quantity, interval, or end date) has changed. Unlike the Status Change Webhook, this event is not about activation, cancellation, or renewal — it only reports field-level updates.

How it works

  • Your webhookUrl (configured in the membership settings) receives an HTTP POST request with a JSON payload.

  • The payload includes:

    • The Action field (always SUBSCRIPTION_UPDATED)

    • The ActionId — unique event correlation key

    • The updated Membership object, containing:

      • Basic membership identifiers (Id, Key, CustomerKey, Metadata)

      • An Updates dictionary describing which fields changed and their new values

  • The webhook may also include contextual fields such as OrderId, IssuedAt, and a Signature for verification.

  • Use this event to synchronize your local records when plan details or billing parameters change.

The Updates object contains only the fields that have actually changed in the membership. Depending on what was modified, it can include any of the following:

  • Name – when the membership’s display name changes.

  • PricePerUnit – when the price per billing unit is updated.

  • Quantity – when the subscribed quantity (such as number of seats or items) changes.

  • EndDate – when the subscription’s end or expiration date is modified.

  • IntervalType – when the billing interval type changes, for example from "Monthly" to "Annually".

  • IntervalCount – when the number of intervals between billing cycles changes, for example from every 1 month to every 3 months.

  • Metadata – Optional merchant-defined free-form string used to attach custom identifiers or correlation data to the subscription.

The payload schema remains consistent across webhook types; only the Action and included membership data differ.

chevron-rightPayload Structure hashtag

Signature Verification

For security, every webhook request is signed so that your system can verify it originates from Paytiko and has not been tampered with.

How it’s generated

The signature is generated using SHA-256 hashing of the merchant’s secret key together with the membership’s OrderId.

Formula:

  • SecretKey — your merchant’s private secret key (never exposed publicly).

  • OrderId — the order identifier associated with the membership or transaction.

Example

If your merchant secret key is:

and the OrderId in the webhook payload is:

then the string to be hashed is:

The resulting SHA-256 hash will be the signature value you should compare against the one provided in the webhook headers.

Validation Steps

  1. Extract the OrderId from the webhook payload.

  2. Concatenate your SecretKey and OrderId with a colon (:).

  3. Generate the SHA-256 hash of this string.

  4. Compare the result with the signature sent in the webhook header.

    • If they match → the webhook is authentic.

    • If not → reject the webhook.

IP Whitelisting

In addition to signature validation, you must also whitelist Paytiko’s official webhook source IP addresses in your firewall or API gateway.

Why this is required

  • Webhooks are sent over the public internet, and malicious actors could attempt to mimic Paytiko’s payload format.

  • Even if a payload looks correct, if it does not come from Paytiko’s trusted infrastructure, it must be rejected.

  • IP whitelisting ensures your server accepts webhook traffic only from Paytiko’s infrastructure.

How it works

  • Paytiko will provide a list of static outbound IP addresses.

  • Your system must configure these IPs as allowed sources for webhook requests.

  • Requests from any other IP must be blocked before signature validation is even attempted.

FAQ

chevron-right❓ How are customers identified?hashtag

Customers are uniquely identified by email within the scope of a single merchant. Creating a customer with the same email is idempotent — the API will return the existing customerKey instead of creating a duplicate.

chevron-right❓ How are memberships identified?hashtag

Memberships are uniquely identified by orderId. Creating a membership with the same orderId is also idempotent — the API will return the existing membership instead of creating a duplicate.

chevron-right❓What happens if I don’t provide endDate for a membership?hashtag

If endDate is omitted, the membership will be infinite and continue until it is explicitly cancelled. If provided, it must be at least 1 hour ahead of current UTC time.

chevron-right❓ How is pricing validated?hashtag
  • totalAmount must equal pricePerUnit × quantity (when both are provided).

  • All amounts must be greater than 0.

  • Currency must be a valid 3-letter ISO code (e.g., USD, EUR).

chevron-right❓ How does billing cycle calculation work?hashtag
  • intervalType defines the base recurrence unit (Daily, Weekly, Monthly, Annually).

  • intervalCount multiplies the base interval (default = 1 if omitted).

    • Example: intervalType=Weekly, intervalCount=2 → every 2 weeks.

  • Edge cases: For end-of-month memberships, if the current month has fewer days, the system will always bill on the last available day of the month.

chevron-right❓ Can memberships be cancelled at the end of the billing cycle instead of immediately?hashtag

No. The Cancel Membership endpoint always cancels immediately. If you want “cancel at end of period” behavior, you must track that in your system and call the API when the period ends.

chevron-right❓ What happens to invoices when a membership is cancelled?hashtag
  • Open invoices → automatically marked as Void.

  • Paid invoices → remain unchanged.

  • Failed invoices → remain unchanged and will not be retried.

chevron-right❓ How does webhook delivery work?hashtag
  • By webhookUrl provided, the system will send event notifications (e.g., payment success/failure).

  • The URL must be a valid absolute HTTPS URL.

  • Merchants should implement idempotency in their webhook handlers, as the same event may be retried if delivery fails.

chevron-right❓ Is the API idempotent?hashtag

Only the following API endpoints are idempotent:

  • Creating customers by email is idempotent.

  • Creating memberships by orderId is idempotent.

chevron-right❓ What format is required for phone numbers?hashtag
  • Example: +48123456789

  • Must contain 8–15 digits, no spaces or formatting characters.

chevron-right❓ What test data should I use?hashtag
  • Use fake but valid-looking data (emails, phone numbers, addresses).

  • For phone, always use a non-existent but valid E.164 number (e.g., +48111222333).

  • For webhook URLs, use test endpoints such as https://webhook.site/....

Last updated