Introduction
The Wixxir Merchant External API allows marketplace and multi-seller platforms to integrate Wixxir payment, installment and Diginote functionality into their existing seller, product and checkout systems.
Merchant platforms can synchronize their sellers and products with Wixxir, configure installment plans, create single-product or basket-based checkout sessions, and notify Wixxir when an order or order item has been delivered.
Wixxir provides two payment integration modes: Merchant API V1 for individual payments and Merchant API V2 for basket and multi-seller checkout flows.
Overview
Using the Wixxir Merchant External API, your platform can:
- Synchronize merchant sellers with Wixxir
- Synchronize products and installment configurations
- Read existing product configuration from Wixxir
- Integrate Wixxir installment plans into Add/Edit Product forms
- Create individual V1 payments
- Create multi-product and multi-seller V2 basket checkouts
- Support single-currency and multi-currency baskets
- Map individual Wixxir payment UUIDs to merchant orders or order items
- Notify Wixxir when products are delivered
- Enable delivery-gated settlement processing
Get Merchant API Key
All Merchant External API requests require a valid Wixxir Merchant API key.
Your API key must be stored securely on your server.
Example environment configuration:
WIXXIR_MERCHANT_API_URL=https://wixxir.com/api/merchant/external
WIXXIR_MERCHANT_API_KEY=YOUR_KEY_HERE
Laravel example:
'wixxir_merchant' => [
'api_url' => env(
'WIXXIR_MERCHANT_API_URL',
'https://wixxir.com/api/merchant/external'
),
'api_key' => env(
'WIXXIR_MERCHANT_API_KEY'
),
],
Important: Never expose your Merchant API key in Blade, frontend JavaScript, browser requests or public widgets.
API Versions
Seller and Product synchronization endpoints are shared by both V1 and V2.
| Feature | V1 | V2 |
|---|---|---|
| Seller Sync | Supported | Supported |
| Product Sync | Supported | Supported |
| Single Product Checkout | Supported | Supported |
| Multi Product Basket | No | Supported |
| Multi Seller Basket | No | Supported |
| Per-item Payment UUID | One payment | One payment per item |
Authentication
Every Merchant External API request must contain your Merchant API key in the request headers.
X-API-KEY: YOUR_MERCHANT_API_KEY
Accept: application/json
Content-Type: application/json
The Merchant identity is resolved by Wixxir from the API key. Do not send merchant_id in the request body.
Connection Test
Use the Ping endpoint to verify your Merchant API connection.
GET https://wixxir.com/api/merchant/external/ping
Headers:
X-API-KEY: YOUR_MERCHANT_API_KEY
Example response:
{
"status": "success",
"message": "Merchant External API connection successful",
"merchant_id": 7
}
Seller Synchronization
Synchronize a seller from your marketplace with Wixxir.
POST https://wixxir.com/api/merchant/external/sellers/sync
Example request:
{
"external_seller_id": "SELLER-1001",
"seller_name": "Example Seller",
"display_name": "Example Store",
"email": "seller@example.com",
"phone": "+13324550910",
"status": true,
"metadata": {
"merchant_seller_id": "SELLER-1001"
}
}
| Parameter | Required | Description |
|---|---|---|
| external_seller_id | Yes | Stable and unique seller identifier in the merchant platform |
| seller_name | Yes | Seller full name |
| display_name | No | Store or public seller name |
| Yes | Seller email address | |
| phone | Yes | Seller phone number including country code |
| status | No | Seller mapping status. Defaults to true |
| metadata | No | Optional merchant-side metadata |
The same external_seller_id must be reused for the same seller. If the mapping already exists, Wixxir updates the existing seller instead of creating a duplicate.
Seller email addresses and phone numbers must be unique across Wixxir User, Seller and Merchant accounts.
Product Synchronization
Synchronize a seller product and its installment plans with Wixxir.
POST https://wixxir.com/api/merchant/external/products/sync
Example:
{
"external_seller_id": "SELLER-1001",
"external_product_id": "PRODUCT-5001",
"name": "Example Product",
"description": "Example description",
"price": 1500,
"currency": "TRY",
"status": true,
"installment_plans": [
{
"name": "5 Installments",
"installment_count": 5,
"interest_rate": 20,
"down_payment_percentage": 20,
"installment_frequency": "monthly",
"priority": 1,
"status": true
}
]
}
The product currency must represent the product's real currency on the merchant platform.
For example:
Merchant Product: 1500 TRY
Wixxir Product Sync: 1500 TRY
Merchant Product: 200 USD
Wixxir Product Sync: 200 USD
The identity combination Merchant + external_seller_id + external_product_id is stable. Re-sending the same product updates the existing Wixxir product.
If no installment plans are sent, the product can still be used for full payment.
Product Configuration
Retrieve the current Wixxir configuration for a synchronized product.
GET https://wixxir.com/api/merchant/external/products/config
Query parameters:
external_seller_id=SELLER-1001
external_product_id=PRODUCT-5001
Example response:
{
"status": true,
"message": "Product configuration retrieved successfully.",
"data": {
"external_seller_id": "SELLER-1001",
"external_product_id": "PRODUCT-5001",
"product_id": 12,
"agent_id": 346,
"merchant_id": 7,
"name": "Example Product",
"description": "Example description",
"price": 1500,
"currency": "TRY",
"status": true,
"installment_plan_count": 1,
"installment_plans": [
{
"installment_plan_id": 26,
"name": "5 Installments",
"description": null,
"installment_count": 5,
"interest_rate": 20,
"down_payment_percentage": 20,
"installment_frequency": "monthly",
"priority": 1,
"status": true
}
]
}
}
This endpoint can be used when opening an Edit Product form, so the merchant does not need to maintain a separate copy of the Wixxir installment configuration in its own database.
Installment Plan Widget
Wixxir provides a public widget for seller-facing installment configuration.
<div id="wixxir-installment-plans"></div>
<script
defer
src="https://wixxir.com/core/public/widgets/installment-plans.js"
data-target="#wixxir-installment-plans"
data-product-form="#product-form"
data-price-field="[name='price']"
data-currency-field="[name='currency']"
data-initial-config="null"
>
</script>
For a multi-currency merchant platform:
-
Connect
data-currency-fieldto the merchant's real product currency field.
For a global / single-currency merchant platform:
<input
type="hidden"
name="wixxir_currency"
value="USD"
>
Then:
data-currency-field="[name='wixxir_currency']"
If the merchant serializes Product forms using AJAX,
use data-input-container so Wixxir's generated
hidden fields are included in the serialized form data.
Keep the defer attribute on the public widget script.
Merchant API V1
Overview
Merchant API V1 creates one individual Wixxir payment.
V1 is designed for an individual seller/product payment. Multi-product or multi-seller baskets should use Merchant API V2.
Create Payment
POST https://wixxir.com/api/merchant/external/payments/create
Example:
{
"external_seller_id": "SELLER-1001",
"external_product_id": "PRODUCT-5001",
"product_name": "Example Product",
"customer_name": "John Doe",
"customer_email": "john@example.com",
"customer_phone": "+13324550910",
"amount": 1500,
"currency": "TRY",
"order_id": "ORDER-1001",
"return_url": "https://merchant.example.com/payment/success",
"cancel_url": "https://merchant.example.com/cart",
"country_code": "US",
"metadata": {
"merchant_order_id": "1001"
}
}
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| external_seller_id | string | Yes | Merchant seller identifier |
| external_product_id | string | Yes | Merchant product identifier |
| product_name | string | Yes | Product name |
| customer_name | string | Yes | Customer full name |
| customer_email | string | Yes | Customer email |
| customer_phone | string | Yes | Customer phone |
| amount | decimal | Yes | Payment amount |
| currency | string | Yes | Three-letter currency code |
| order_id | string | No | Merchant order reference |
| return_url | URL | No | Successful checkout return URL |
| cancel_url | URL | No | Checkout cancellation URL |
| country_code | string | No | Customer country code. Default: US |
| metadata | object | No | Merchant metadata |
Currency Handling
V1 requires a three-letter currency value in the payment request.
If Wixxir resolves the synchronized product with an active installment configuration, the synchronized Product currency is used as the payment currency.
If the product cannot be resolved for installment use, the request currency is used and the payment remains full-payment-only.
Response Format
Example success response:
{
"status": "success",
"message": "Payment created successfully.",
"uuid": "PAYMENT-UUID",
"client_secret": null,
"checkout_url": "https://wixxir.com/merchant-checkout/PAYMENT-UUID",
"seller": {
"external_seller_id": "SELLER-1001",
"agent_id": 346,
"display_name": "Example Store"
},
"product": {
"id": 12,
"external_product_id": "PRODUCT-5001",
"name": "Example Product",
"installment_available": true
}
}
Always redirect the customer using the checkout_url returned by Wixxir.
Do not construct the Wixxir checkout URL on the merchant platform.
Checkout Flow
Merchant Order
↓
POST /payments/create
↓
Wixxir individual payment UUID
↓
checkout_url
↓
Redirect customer to Wixxir
↓
Customer selects Full or Installment payment
↓
Digital Signature when required
↓
Payment processing
↓
Merchant return_url
Merchant API V2
Overview
Merchant API V2 provides basket-based checkout.
V2 supports:
- Single seller + single product
- Single seller + multiple products
- Multiple sellers + multiple products
- Single-currency baskets
- Mixed-currency baskets
Each basket item creates its own individual Wixxir payment. All item payments are linked by one checkout_group_uuid.
Basket Payment
POST https://wixxir.com/api/merchant/external/basket/payments/create
Example:
{
"customer_name": "John Doe",
"customer_email": "john@example.com",
"customer_phone": "+13324550910",
"country_code": "US",
"order_id": "ORDER-2001",
"return_url": "https://merchant.example.com/payment/success",
"cancel_url": "https://merchant.example.com/cart",
"items": [
{
"external_seller_id": "SELLER-A",
"external_product_id": "PRODUCT-A",
"amount": 100,
"currency": "USD",
"metadata": {
"merchant_order_detail_id": "101"
}
},
{
"external_seller_id": "SELLER-B",
"external_product_id": "PRODUCT-B",
"amount": 2500,
"currency": "TRY",
"metadata": {
"merchant_order_detail_id": "102"
}
}
],
"metadata": {
"merchant_order_id": "2001",
"merchant_order_reference": "ORDER-2001"
}
}
Basket Items
| Field | Required | Description |
|---|---|---|
| external_seller_id | Yes | Merchant seller identifier |
| external_product_id | Yes | Merchant product identifier |
| amount | Yes | Original item / line amount |
| currency | Yes | Original item currency |
| checkout_amount | No | Merchant-converted checkout amount |
| checkout_currency | No | Merchant checkout currency |
| metadata | No | Stable merchant item identity or additional data |
amount is the real line amount in the item's original currency. It does not have to equal the synchronized Product unit price.
For example:
Product unit price: 100 USD
Quantity: 2
Basket line total: 200 USD
items[].amount = 200
items[].currency = USD
Currency Handling
Every V2 basket item must contain its original amount and original currency.
Single-Currency Basket
Example:
Item A = 100 USD
Item B = 250 USD
Item C = 80 USD
If all basket items use the same original currency, Wixxir preserves the original amounts and currency.
No currency conversion is applied.
Mixed-Currency Basket
Example:
Item A = 100 USD
Item B = 2500 TRY
Item C = 75 EUR
A mixed-currency basket can use either merchant-provided conversion values or Wixxir fallback conversion.
Merchant Conversion
If the merchant platform already converts basket amounts to a common checkout currency, it may send:
{
"amount": 2500,
"currency": "TRY",
"checkout_amount": 60.25,
"checkout_currency": "USD"
}
Merchant conversion is used only when:
- every item contains a valid checkout_amount
- every item contains a valid checkout_currency
- all items use the same checkout currency
If these conditions are satisfied, the merchant-provided checkout values are authoritative and Wixxir does not convert them again.
Wixxir Fallback Conversion
If a mixed-currency basket does not contain a complete and consistent merchant conversion set, Wixxir ignores the merchant checkout conversion values and performs fallback conversion for the complete basket.
The current Wixxir fallback checkout currency is:
USD
A basket never mixes merchant conversion and Wixxir fallback conversion item-by-item. The complete mixed-currency basket uses one conversion source.
Metadata
Basket-level and item-level metadata are supported.
Item metadata is especially useful for mapping each Wixxir payment back to the merchant's local order item.
Recommended example:
{
"metadata": {
"merchant_order_detail_id": "101"
}
}
The metadata field name is merchant-defined.
You may use another stable identifier such as
order_item_id.
Response Format
Example:
{
"status": "success",
"message": "Basket payment checkout created successfully.",
"checkout_group_uuid": "CHECKOUT-GROUP-UUID",
"checkout_url":
"https://wixxir.com/merchant-basket-checkout/CHECKOUT-GROUP-UUID",
"payment_count": 2,
"payments": [
{
"uuid": "PAYMENT-UUID-A",
"external_seller_id": "SELLER-A",
"external_product_id": "PRODUCT-A",
"agent_id": 346,
"product_id": 12,
"product_name": "Product A",
"original_amount": 100,
"original_currency": "USD",
"amount": 100,
"currency": "USD",
"metadata": {
"merchant_order_detail_id": "101"
}
},
{
"uuid": "PAYMENT-UUID-B",
"external_seller_id": "SELLER-B",
"external_product_id": "PRODUCT-B",
"agent_id": 347,
"product_id": 13,
"product_name": "Product B",
"original_amount": 2500,
"original_currency": "TRY",
"amount": 60.25,
"currency": "USD",
"metadata": {
"merchant_order_detail_id": "102"
}
}
]
}
checkout_group_uuid identifies the whole checkout session.
Each item also receives its own payments[].uuid.
Payment UUID Mapping
Persist each individual Wixxir payment UUID against the corresponding merchant order item.
Example:
$wixxirPayments =
$wixxirData['payments']
?? [];
foreach ($wixxirPayments as $wixxirPayment) {
$paymentUuid =
$wixxirPayment['uuid']
?? null;
$merchantOrderDetailId =
$wixxirPayment['metadata']['merchant_order_detail_id']
?? null;
if (
!$paymentUuid
|| !$merchantOrderDetailId
) {
continue;
}
/*
* Persist:
*
* Merchant Order Item
* <->
* Wixxir payment UUID
*/
}
Do not use checkout_group_uuid as the item delivery identifier.
Checkout Flow
Merchant Basket
↓
Merchant creates local Order / Order Items
↓
POST /basket/payments/create
↓
Wixxir validates Seller/Product mappings
↓
Single-currency OR mixed-currency decision
↓
Individual payment created for each basket item
↓
checkout_group_uuid
↓
payments[]
↓
checkout_url
↓
Merchant stores item ↔ payment UUID mapping
↓
Merchant redirects customer to Wixxir
↓
Customer selects payment option per item
↓
Digital Signature when required
↓
Combined payment processing
↓
Return to merchant
Delivery Status
Overview
Wixxir Merchant settlement is delivery-gated.
After the merchant platform has successfully marked the related product or order item as delivered, the merchant should notify Wixxir.
POST https://wixxir.com/api/merchant/external/payments/delivery-status
Delivery notification is associated with the individual Wixxir payment UUID.
V1 Delivery
Merchant local sale/order
↓
POST /payments/create
↓
Wixxir payment UUID
↓
Merchant stores payment UUID
↓
Customer payment
↓
Later: product/order is Delivered
↓
POST /payments/delivery-status
V1 uses one individual payment UUID for the payment.
V2 Delivery
V2 delivery is item-level.
Basket
├── Item A → payment UUID A
├── Item B → payment UUID B
└── Item C → payment UUID C
If Item A is delivered:
payment UUID A
→ delivered
Items B and C
→ unchanged
One item's delivery status does not modify other item payments in the same basket.
Request Contract
Headers:
X-API-KEY: YOUR_MERCHANT_API_KEY
Accept: application/json
Content-Type: application/json
Request:
{
"payment_uuid": "PAYMENT-UUID",
"delivery_status": "delivered"
}
Example Laravel call:
try {
$wixxirResponse =
Http::acceptJson()
->withHeaders([
'X-API-KEY' =>
config(
'services.wixxir_merchant.api_key'
),
])
->post(
rtrim(
config(
'services.wixxir_merchant.api_url'
),
'/'
)
. '/payments/delivery-status',
[
'payment_uuid' =>
$wixxirPaymentUuid,
'delivery_status' =>
'delivered',
]
);
if (!$wixxirResponse->successful()) {
Log::warning(
'Wixxir delivery synchronization failed.',
[
'payment_uuid' =>
$wixxirPaymentUuid,
'http_status' =>
$wixxirResponse->status(),
'response' =>
$wixxirResponse->json(),
]
);
}
} catch (\Throwable $exception) {
Log::warning(
'Wixxir delivery synchronization exception.',
[
'payment_uuid' =>
$wixxirPaymentUuid,
'error' =>
$exception->getMessage(),
]
);
}
Call Wixxir only after the merchant's local delivery update has successfully completed.
A Wixxir API/network error should not roll back a successfully completed merchant delivery operation.
Settlement Eligibility
The delivered notification satisfies the delivery requirement used by Wixxir's settlement process.
The merchant should send delivered only when the corresponding product/order item has actually been delivered.
Cancellation handling is intentionally outside the scope of this public delivery documentation and may be added separately when the merchant cancellation lifecycle is finalized.
Security
API Key Security
The Wixxir Merchant API key is a server-side secret.
Never expose it in:
- Blade templates
- Frontend JavaScript
- Public HTML
- Browser requests
- Public installment widgets
Server-side Requests
All authenticated API calls should originate from the merchant backend.
Example:
Http::acceptJson()
->withHeaders([
'X-API-KEY' =>
config(
'services.wixxir_merchant.api_key'
),
]);
Error Handling
Seller and Product synchronization should normally run after the merchant's local Seller/Product save operation.
A Wixxir synchronization failure should be logged, but it should not automatically invalidate a successfully completed local Seller or Product save.
Checkout creation is different: if Wixxir checkout cannot be created, the payment flow should stop and the customer should remain on or return to the merchant checkout/cart.
Delivery synchronization should run after the local delivery update has completed. A Wixxir delivery API error should be logged and handled operationally without rolling back the merchant's already completed local delivery.
Support
For Merchant API integration support:
support@wixxir.com