Tapaya
OverviewPlatform APIMerchant Onboarding API

Merchant Onboarding API

Create merchants and submit or invite them to onboarding through the Tapaya Platform API.

All requests on this page use your Server Secret Token. See Authentication.

One onboarding for In-Store and Online

A merchant can request In-Store Acceptance, Online Payments, or both in one onboarding application. This page applies to every integration: the Accept SDK, the Tapaya Terminal app, and Checkout. Use it to create and manage merchants through the API instead of the Tapaya Platform UI. Request the payment capabilities the merchant needs. An in-store approval alone does not enable online payments.

Creating a merchant with POST /integrator/merchant, or with POST /merchant/auth/register in an Accept SDK integration, creates its account, but the merchant cannot process live payments in store or online until onboarding is complete. For online payments, request the Checkout capability and wait for online processor approval and gateway setup. Merchants appear automatically in Checkout settings, where you can check readiness and configure keys and wallets. Tapaya supports several onboarding experiences; all can be managed from the Tapaya Platform UI and automated where appropriate.

FlowWhen to use itAPI entry point
Tapaya Platform UIYour operations team completes onboarding on the merchant's behalf.Create or select the merchant in the Tapaya Platform UI and open the hosted onboarding there.
Your own UIYou collect and validate onboarding information in your product.Validate sections with POST /integrator/merchant/onboarding/validate/*, then submit with POST /integrator/merchant/onboarding. Detailed below.
Email inviteA known merchant receives a single-use invitation to self-onboard.Send an invite with POST /integrator/merchant/send-registration-invite; include merchantToken to bind the invite to an existing merchant shell, then list or revoke it through /integrator/merchant/invites.
Campaign linkMultiple or not-yet-known merchants use a reusable self-registration link.Create a link with POST /integrator/merchant/reusable-registration-invites; list or revoke links through the same resource.

For a detailed comparison of these flows, see the Merchant Onboarding guide.

Request online payment capabilities

POST /integrator/merchant/onboarding requires capability. Use the same capability when validating the business profile:

ValueCapabilityChannel details
1BothSupply terminal and online. Each channel requires its own approval.
2TerminalsSupply terminal for in-store payments.
3CheckoutSupply online for online payments. No terminal is required.

For Checkout, add the following top-level fields alongside the merchant's identity, address, shared business, and KYB data. The same channel fields apply to POST /integrator/merchant/onboarding/validate/business:

{
	"capability": 3,
	"online": {
		"mcc": "5411",
		"statementDescriptor": "ACME CORP",
		"productDescription": "Groceries sold online",
		"averageItemValue": 2500,
		"expectedMonthlyTurnover": 500000,
		"url": "https://www.acme.example.com",
		"purchaseChargeTiming": 1,
		"averageDeliveryDays": 2,
		"topCountries": [{ "countryId": 1, "percentage": 100 }]
	}
}

Amounts are in minor currency units. The online website must use HTTP or HTTPS and its hostname must contain www. statementDescriptor is 5 to 22 characters. purchaseChargeTiming is 1 for order placed, 2 for shipped, or 3 for received. averageDeliveryDays is 0 to 999. Supply one to four unique topCountries whose percentages total 100.

Keep shared support and financial details in business. In channel-section mode, put MCC, statement descriptor, product description, and transaction estimates in the relevant terminal or online object. Validate the payload before submitting onboarding, and resolve the returned channel-specific field errors.

Invite a Merchant to Complete Hosted Onboarding

Use this flow when Tapaya should host the KYB form, but you still want to control merchant creation from your backend.

Recommended when you own merchantToken

If your system owns the merchant identifier used later by the SDK or your back office, first create the merchant shell with POST /merchant/auth/register or POST /integrator/merchant, then call POST /integrator/merchant/send-registration-invite with the same merchantToken. This keeps the hosted onboarding attached to that merchant instead of creating a second one.

The recommended sequence is:

  1. Create the merchant shell:
    • POST /merchant/auth/register, or
    • POST /integrator/merchant
  2. Send the hosted onboarding invite with POST /integrator/merchant/send-registration-invite
  3. Share the returned registrationUrl with the merchant if needed, and let them complete the Tapaya-hosted form
  4. Poll merchant readiness through GET /integrator/merchant/{merchantId}/status

Endpoint: POST /integrator/merchant/send-registration-invite

curl -X 'POST' 'https://api.tapaya.com/integrator/merchant/send-registration-invite' \
-H 'Content-Type: application/json' \
-H 'Authorization: REPLACE_ME' \
-d '{
        "email": "admin@acme.com",
        "merchantToken": "unique_merchant_id_from_your_db"
    }'

Parameters:

FieldTypeRequiredDescription
emailstring✓Email address that should receive the hosted onboarding link.
merchantTokenstringExisting merchant token to bind the invite to. Use this when you already created the merchant shell and want the hosted onboarding to fill that same merchant. If omitted, completing the invite creates a new merchant.

Responses:

CodeDescription
200Invite created. Response includes registrationUrl
400Request validation error
401Unauthorized
404Organization or merchant not found
409Conflict

Response body:

{
    "registrationUrl": "https://platform.tapaya.com/invite-merchant?token=...&merchantToken=unique_merchant_id_from_your_db"
}

Tapaya also attempts to email this link. Email delivery is best-effort, so always treat the returned registrationUrl as the source of truth for your UI and support tooling.

Do not confuse this with merchant-user invite

POST /integrator/merchant/{merchantId}/invite is a different flow. It invites a platform user to access an already-existing merchant account. It does not start KYB onboarding and does not create or update a merchant profile.

Submit Onboarding through the API

If you want to collect onboarding information in your own product instead of sending merchants to the Tapaya Platform, submit it directly. Validate each section as the merchant fills it in with the validate/* endpoints below, then submit everything in one call, which creates the merchant and its onboarding profile together, and registers it with your organization's preferred payment processor.

Merchant consent and privacy notice

Before submitting onboarding details through the API, you must obtain the merchant's consent to the Tapaya Integrators Terms and Conditions and Tapaya Privacy Policy. Add a checkbox to your onboarding form that links to both documents, or link to the Tapaya documents from the terms text to which the merchant consents. You must also list Tapaya as a data processor in your own privacy policy.

Merchant not created on failure

POST /integrator/merchant/onboarding creates the merchant and submits onboarding in a single call. If the onboarding data is invalid, it returns 422 with field-level errors and no merchant is created; there is no partially-onboarded merchant to clean up or resume.

Validate Identity

Endpoint: POST /integrator/merchant/onboarding/validate/identity

curl -X 'POST' 'https://api.tapaya.com/integrator/merchant/onboarding/validate/identity' \
-H 'Content-Type: application/json' \
-H 'Authorization: REPLACE_ME' \
-d '{
        "legalName": "Acme Corp s.r.o.",
        "businessTypeId": 2,
        "email": "admin@acme.com",
        "registrationNumber": "12345678",
        "vatNumber": "CZ12345678",
        "incorporationDate": "2018-04-01"
    }'

Parameters:

FieldTypeRequiredDescription
legalNamestring✓Legal name of the business or individual account holder.
businessTypeIdint✓Type of business entity (BusinessTypeEnum).
emailstring✓Contact email address.
registrationNumberstring✓Official business registration number. Checked for duplicates within your
organization.
vatNumberstringVAT registration number, if applicable.
incorporationDatedateDate the business was legally incorporated (YYYY-MM-DD).

Response body:

{
    "valid": true,
    "errors": []
}

A registrationNumber already used by another merchant in your organization comes back as a valid: false error with code: "DUPLICATE_REGISTRATION_NUMBER" rather than a 409; this endpoint always returns 200.

Validate Address

Endpoint: POST /integrator/merchant/onboarding/validate/address

curl -X 'POST' 'https://api.tapaya.com/integrator/merchant/onboarding/validate/address' \
-H 'Content-Type: application/json' \
-H 'Authorization: REPLACE_ME' \
-d '{
        "line1": "Wenceslas Square 1",
        "city": "Prague",
        "postalCode": "11000",
        "countryId": 1
    }'

Parameters:

FieldTypeRequiredDescription
line1string✓First line of the street address.
line2stringSecond line of the street address, if applicable.
citystring✓City name.
postalCodestring✓Postal or ZIP code.
statestringState or region, if applicable.
countryIdint✓Country (CountryEnum).

Response body: same {valid, errors} shape as Validate Identity.

Validate Business Profile

Endpoint: POST /integrator/merchant/onboarding/validate/business

curl -X 'POST' 'https://api.tapaya.com/integrator/merchant/onboarding/validate/business' \
-H 'Content-Type: application/json' \
-H 'Authorization: REPLACE_ME' \
-d '{
        "capability": 2,
        "mcc": "5411",
        "url": "https://acme.example.com",
        "supportPhone": "+420123456789",
        "statementDescriptor": "ACME CORP"
    }'

Parameters:

FieldTypeRequiredDescription
capabilityint✓Use the capability you will submit for onboarding. For Checkout or Both, supply the channel details.
mccstring✓Four-digit Merchant Category Code. In channel-section mode, use terminal.mcc or online.mcc.
urlstringBusiness website URL. Either url or productDescription is required.
productDescriptionstringDescription of products or services. Either url or productDescription is
required.
supportPhonestring✓Customer support phone number, in E.164 format.
statementDescriptorstring✓Text shown on customer bank statements (1–22 characters).
averageItemValuelongAverage transaction value, in minor currency units.
expectedMonthlyTurnoverlongExpected monthly revenue, in minor currency units.
numberOfEmployeesintNumber of employees at the business.
annualTurnoverlongAnnual revenue, in minor currency units.
balanceSheetTotallongTotal balance sheet value, in minor currency units.

Response body: same {valid, errors} shape as Validate Identity.

Validate KYB

Endpoint: POST /integrator/merchant/onboarding/validate/kyb

Provide exactly one of individual (sole trader / self-employed) or company. For a company, list every owner, director, and authorized signatory in people.

curl -X 'POST' 'https://api.tapaya.com/integrator/merchant/onboarding/validate/kyb' \
-H 'Content-Type: application/json' \
-H 'Authorization: REPLACE_ME' \
-d '{
        "businessTypeId": 2,
        "bankAccount": {
            "iban": "CZ6508000000192000145399",
            "bic": "GIBACZPX",
            "currencyId": 1,
            "beneficiaryName": "Acme Corp s.r.o."
        },
        "company": {
            "name": "Acme Corp s.r.o.",
            "registrationNumber": "12345678",
            "people": [
                {
                    "email": "jane@acme.com",
                    "firstName": "Jane",
                    "lastName": "Doe",
                    "role": {
                        "isOwner": true,
                        "isAuthorizedSignatory": true
                    }
                }
            ]
        }
    }'

Parameters:

FieldTypeRequiredDescription
businessTypeIdintType of business entity (BusinessTypeEnum); determines whether individual or
company fields are required.
bankAccountobjectPayout bank account (account number/IBAN + BIC, currency, beneficiary and bank
address).
individualobjectIndividual owner details, for sole traders. Mutually exclusive with company.
companyobjectCompany details, including a people array of owners, directors, and authorized
signatories, plus an optional verificationDocument. Mutually exclusive with individual.

Each person in people (and individual) carries role.isOwner / isDirector / isRepresentative / isAuthorizedSignatory flags, plus optional identity fields (dateOfBirth, nationalityCountryId, officialIdType/officialIdNumber, address, ownershipPercentage, verificationDocuments). A person entry must be either invite-only or fully detailed; partially filled people are rejected. There are two ways to submit a person:

  • Invite-only: submit just email and a role. The person receives an email with instructions to complete their own personal details and identity verification directly, including uploading their own ID document; you don't need to collect anything else for them, and no document upload is required on your side.
  • Fully detailed: submit all of the person's personal details (name, date of birth, official ID, address, etc.) yourself. In this case you must also upload an ID document for that person; this is required, not optional, for every fully-detailed person.

Documents are uploaded after the merchant exists, because the document upload endpoint needs the merchantId returned by Create Merchant with Onboarding. Each person's upload is matched to them by relatedOfficialIdNumber. The optional verificationDocuments.identityDocument, verificationDocuments.additionalDocument, and company.verificationDocument fields each take a {frontFileId, backFileId} object and can only reference files that were already uploaded, so omit them when creating a new merchant.

Regardless of how many people are invite-only vs. fully detailed, you must always upload the company's registration/incorporation document before the merchant can be submitted for KYC review.

Response body: same {valid, errors} shape as Validate Identity.

Create Merchant with Onboarding

Submits everything from the previous four steps in one call, creates the merchant, and registers it with your organization's preferred payment processor.

Endpoint: POST /integrator/merchant/onboarding

curl -X 'POST' 'https://api.tapaya.com/integrator/merchant/onboarding' \
-H 'Content-Type: application/json' \
-H 'Authorization: REPLACE_ME' \
-d '{
        "name": "Acme Corp",
        "capability": 2,
        "merchantToken": "unique_merchant_id_from_your_db",
        "identity": {
            "legalName": "Acme Corp s.r.o.",
            "businessTypeId": 2,
            "email": "admin@acme.com",
            "registrationNumber": "12345678",
            "vatNumber": "CZ12345678"
        },
        "address": {
            "line1": "Wenceslas Square 1",
            "city": "Prague",
            "postalCode": "11000",
            "countryId": 1
        },
        "business": {
            "mcc": "5411",
            "url": "https://acme.example.com",
            "supportPhone": "+420123456789",
            "statementDescriptor": "ACME CORP"
        },
        "kyb": {
            "bankAccount": {
                "iban": "CZ6508000000192000145399",
                "bic": "GIBACZPX",
                "currencyId": 1,
                "beneficiaryName": "Acme Corp s.r.o."
            },
            "company": {
                "people": [
                    {
                        "email": "jane@acme.com",
                        "firstName": "Jane",
                        "lastName": "Doe",
                        "role": {
                            "isOwner": true,
                            "isAuthorizedSignatory": true
                        }
                    }
                ]
            }
        }
    }'

Parameters:

FieldTypeRequiredDescription
capabilityint✓1 for Both, 2 for Terminals, or 3 for Checkout. See online payment capabilities.
terminalobjectBy capabilityTerminal channel details for Terminals or Both.
onlineobjectBy capabilityOnline channel details for Checkout or Both.
namestring✓The name of the merchant.
merchantTokenstringA unique, stable identifier from your system. If not provided, a random token is
generated.
identityobject✓Same shape as Validate Identity.
addressobject✓Same shape as Validate Address.
businessobject✓Same shape as Validate Business Profile.
kybobject✓Same shape as Validate KYB.

Responses:

CodeDescription
201Merchant created and onboarding submitted
422Onboarding data invalid, see errors; merchant is not created

Response body (201):

{
    "merchantId": "018f8f2a-3b1e-7c2a-9f1a-2e6a1b7c4d3e",
    "merchantToken": "unique_merchant_id_from_your_db",
    "name": "Acme Corp",
    "email": "admin@acme.com",
    "processors": [
        {
            "processorId": 5,
            "registered": true,
            "onboardingUrl": null
        }
    ]
}

onboardingUrl is populated when the processor requires the merchant to complete an additional hosted onboarding flow (e.g. identity verification) before it can process live payments.

Response body (422):

{
    "errors": [
        {
            "step": "identity",
            "field": "registrationNumber",
            "message": "A merchant with this registration number is already onboarded under this integrator (merchantId: 018f8f2a-3b1e-7c2a-9f1a-2e6a1b7c4d3e).",
            "code": "DUPLICATE_REGISTRATION_NUMBER"
        }
    ]
}

Upload a Person's ID Document

Required for every fully-detailed person in kyb.company.people / kyb.individual (see Validate KYB); invite-only people upload their own instead, via the emailed link.

Endpoint: POST /integrator/merchant/{merchantId}/document

Request body is multipart/form-data, not JSON.

curl -X 'POST' 'https://api.tapaya.com/integrator/merchant/018f8f2a-3b1e-7c2a-9f1a-2e6a1b7c4d3e/document' \
-H 'Authorization: REPLACE_ME' \
-F 'paymentProcessorId=5' \
-F 'documentType=2' \
-F 'relatedOfficialIdNumber=123456789' \
-F 'frontFile=@./jane-doe-id-front.jpg' \
-F 'backFile=@./jane-doe-id-back.jpg'

Parameters:

FieldTypeRequiredDescription
paymentProcessorIdint✓Always 5.
documentTypeint✓Type of document (DocumentTypeEnum: 1 Other, 2 Id, 3 Address, 4 Company,
5 BankStatement, 6 Passport, 7 RecentFinancials).
frontFilefile✓Front side of the document image.
backFilefileBack side of the document image, if applicable.
relatedOfficialIdNumberstringThe person's officialIdNumber from Validate KYB.
Required only when documentType is individual-bound (e.g. Id, Passport, Address); ignored otherwise.
submitMerchantbooleanLeave unset/false here: a person's ID is not the final upload of the batch.
Only set true on the company document upload once every person's document has been
uploaded.

Response body (200):

{
    "frontFileId": "file_1NqtHo2eZvKYlo2CZPg8Xt5h",
    "backFileId": "file_1NqtHp2eZvKYlo2CRTg9Xm3k",
    "uploadedAt": "2026-07-17T12:00:00Z"
}

Upload the Company Document

Required exactly once per merchant. If person details were not filled in, the authorized signatory will be able to upload this using the link from the onboarding email and this endpoint does not need to be called.

Endpoint: POST /integrator/merchant/{merchantId}/document

Request body is multipart/form-data, not JSON.

curl -X 'POST' 'https://api.tapaya.com/integrator/merchant/018f8f2a-3b1e-7c2a-9f1a-2e6a1b7c4d3e/document' \
-H 'Authorization: REPLACE_ME' \
-F 'paymentProcessorId=5' \
-F 'documentType=4' \
-F 'frontFile=@./acme-corp-register-extract.pdf' \
-F 'submitMerchant=true'

Parameters:

FieldTypeRequiredDescription
paymentProcessorIdint✓Always 5.
documentTypeint✓Always 4 (Company) for this step.
frontFilefile✓The company's registration/incorporation document.
submitMerchantbooleanSet to true to trigger the processor's KYC review now that every required
document has been uploaded. Defaults to false.

Response body (200):

{
    "frontFileId": "file_1NqtHo2eZvKYlo2CZPg8Xt5h",
    "backFileId": null,
    "uploadedAt": "2026-07-17T12:00:00Z"
}