Payment Webhooks
Detailed information about payment webhook events including payment.paid and payment.refund.
payment.paid
The payment.paid event is triggered when a payment is successfully completed in the system.
Event Properties
| Field | Type | Description |
|---|---|---|
| id | string | Unique identifier for the payment transaction |
| trade_no | string | Unique trade number for the transaction |
| currency | string | Currency code (ISO 4217 format) |
| amount | integer | Total transaction amount |
| original_amount | integer | Original transaction amount before refunds/adjustments |
| refunded_amount | integer or null | Refunded amount (null if no refund) |
| paid_at | string | Timestamp of payment completion (ISO 8601 format, e.g. "2023-12-04T18:45:44+08:00" or "2023-12-04T10:45:44Z") |
| created_at | string | Timestamp of transaction creation (ISO 8601 format) |
| refunded_at | string or null | Timestamp of refund if applicable (ISO 8601 format) |
| payment_state | string | Current payment state (paid, refunding, refunded, failed) |
| payment_type | string | Payment method (credit, web_atm, atm, cvs, line_pay) |
| affiliate_code | string or null | Associated affiliate code |
| remark | string or null | Additional order notes |
User Information
| Field | Type | Description |
|---|---|---|
| user.id | string | Unique user identifier |
| user.email | string | User's email address |
| user.name | string | User's name |
| user.phone_number | string | User's phone number |
| user.third_party_id | string | Third-party system user identifier |
Payment Method Details
| Field | Type | Description |
|---|---|---|
| payment_method_details.last_four | string or null | Last four digits of credit card (if applicable) |
| payment_method_details.brand | string or null | Credit card brand (if applicable) |
The brand field can have the following values:
visa: Visa credit/debit cardmastercard: Mastercard credit/debit cardjcb: JCB credit cardunionpay: UnionPay cardamex: American Express carddinersclub: Diners Club carddiscover: Discover cardunknown: Card brand could not be determined
Line Items
Each item in the lineitems array contains:
| Field | Type | Description |
|---|---|---|
| name | string | Item name |
| quantity | integer | Quantity purchased |
| amount | integer | Current amount for this item (may reflect partial or no refunds) |
| refunded_amount | integer | Refunded amount for this item (0 if no refund applied to this item) |
| item_type | string | Item type (CurriculumPlan, Ticket, MembershipPlan, DigitalProduct, OrderBump) |
| item_id | string | Unique item identifier |
| item_slug | string | URL-friendly item identifier |
| product_type | string | Product type (Course, Event, MembershipPlan, DigitalProduct) |
| product_id | string | Unique product identifier |
| order_bump_details | object or null | Additional details for OrderBump items (only present when item_type is "OrderBump") |
| metadata | object or null | Custom metadata key-value pairs for this item (only present when the External Metadata feature is enabled) |
When item_type is "OrderBump", the order_bump_details field will be present with the following structure:
| Field | Type | Description |
|---|---|---|
| item_type | string | Type of the order bump item (e.g., "CurriculumPlan") |
| item_id | string | Unique identifier of the order bump item |
| item_slug | string | URL-friendly identifier of the order bump item |
If item_type is not "OrderBump", the order_bump_details field will not be present in the lineitem.
The metadata field is a flat object of string key-value pairs. It is only present when your school has the External Metadata feature enabled and the item has metadata defined. Plan-level metadata takes precedence over product-level metadata when keys conflict.
Additional Information
| Field | Type | Description |
|---|---|---|
| coupon | object or null | Applied coupon details |
| shipping_address | object | Shipping address information |
| invoice | object | Invoice details |
| custom_data | array of objects | Custom data fields |
| refund_history | array of objects or null | History of refunds (if any) |
For detailed descriptions of fields within nested objects (coupon, shipping_address, invoice, custom_data, refund_history), please refer to the full documentation.
Invoice Details
| Field | Type | Description |
|---|---|---|
| state | string | Invoice state (e.g., "issued") |
| number | string | Invoice number |
| buyer_ubn | string | Buyer's Unified Business Number (null for individual buyers) |
| buyer_name | string | Name of the buyer |
| category | string | Invoice category (b2b or b2c) |
| carrier_type | string | Type of carrier for e-invoice (member, certificate, or mobile) |
| carrier_num | string | Carrier number for e-invoice (when applicable) |
| donation | boolean | Indicates if the invoice is for donation (only for b2c) |
| love_code | string | Donation institution code (only present when donation is true) |
Notes:
- The
categoryfield can be either "b2b" (business-to-business) or "b2c" (business-to-consumer). - The
carrier_numfield is only present whencarrier_typeis "certificate" or "mobile". - The
donationfield is only applicable whencategoryis "b2c". - The
love_codefield is only present whendonationis true.
Example Payload
{
"type": "payment.paid",
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"user": {
"id": "00f7407f-219e-4ada-9390-28934d7398d5",
"email": "demo@kaik.io",
"name": "Kaik",
"phone_number": "+886911222333",
"third_party_id": "123123"
},
"trade_no": "DEM2022053167602AF30",
"currency": "TWD",
"amount": 1800,
"paid_at": "2022-05-31T11:28:31Z",
"created_at": "2022-05-31T11:26:42Z",
"refunded_at": null,
"refunded_amount": null,
"original_amount": 1800,
"payment_state": "paid",
"payment_type": "credit",
"payment_method_details": {
"last_four": "1234",
"brand": "visa"
},
"affiliate_code": "newswebPAGE7",
"remark": "Order note",
"lineitems": [
{
"name": "Course Name 123",
"quantity": 1,
"amount": 500,
"refunded_amount": 0,
"item_type": "CurriculumPlan",
"item_id": "51e07cb8-e450-4ed4-8b54-e0144d4da793",
"item_slug": "test-slug",
"product_type": "Course",
"product_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"metadata": {
"crm_id": "sample-crm_id",
"source": "sample-source"
}
},
{
"name": "Course Name",
"quantity": 1,
"amount": 1000,
"refunded_amount": 0,
"item_type": "CurriculumPlan",
"item_id": "f8a7b6c5-d4e3-2f1g-9h8i-7j6k5l4m3n2o",
"item_slug": "test-slug",
"product_type": "Course",
"product_id": "a1b2c3d4-e5f6-7890-1234-567890abcdef"
},
{
"name": "Course Bonus Package",
"quantity": 1,
"amount": 300,
"refunded_amount": 0,
"item_type": "OrderBump",
"item_id": "c5d6e7f8-g9h0-i1j2-k3l4-m5n6o7p8q9r0",
"item_slug": "course-bonus-package",
"product_type": "Course",
"product_id": "s1t2u3v4-w5x6-y7z8-9a0b-c1d2e3f4g5h6",
"order_bump_details": {
"item_type": "CurriculumPlan",
"item_id": "h8i9j0k1-l2m3-n4o5-p6q7-r8s9t0u1v2w3",
"item_slug": "course-bonus-package"
}
}
],
"refund_history": [],
"coupon": {
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"name": "30% Off",
"code": "30p-OFF"
},
"shipping_address": {
"city": "Taipei",
"district": "Songshan District",
"postal_code": "105065",
"address": "xxxxx",
"full_address": "105065 Taipei City, Songshan District, xxx"
},
"invoice": {
"state": "issued",
"number": "BL90912974",
"buyer_ubn": null,
"buyer_name": "Kaik Demo",
"category": "b2c",
"carrier_type": "mobile",
"carrier_num": "/0000001",
"donation": false,
"love_code": null
},
"custom_data": [
{
"field_id": "xxxxxx",
"label": "Field One Name",
"type": "multi_select",
"values": ["A", "B"],
"position": 0
},
{
"field_id": "xxxxxx",
"label": "Field Two Name",
"type": "radio",
"values": ["1"],
"position": 1
},
{
"field_id": "xxxxxx",
"label": "Field Three Name",
"type": "text",
"values": ["xxxxx"],
"position": 2
}
]
}
}payment.refund
The payment.refund event is triggered when a refund is processed for a payment in the system.
Event Properties
| Field | Type | Description |
|---|---|---|
| id | string | Unique identifier for the payment transaction |
| trade_no | string | Unique trade number for the transaction |
| currency | string | Currency code (ISO 4217 format) |
| amount | integer | Current transaction amount after refund |
| original_amount | integer | Original transaction amount before refund |
| refunded_amount | integer | Total refunded amount |
| paid_at | string | Timestamp of original payment completion (ISO 8601 format, e.g. "2023-12-04T18:45:44+08:00" or "2023-12-04T10:45:44Z") |
| created_at | string | Timestamp of transaction creation (ISO 8601 format) |
| refunded_at | string | Timestamp of latest refund (ISO 8601 format) |
| payment_state | string | Current payment state (refunding, refunded) |
| payment_type | string | Original payment method (credit, web_atm, atm, cvs, line_pay) |
| affiliate_code | string or null | Associated affiliate code |
| remark | string or null | Additional order notes |
User Information
| Field | Type | Description |
|---|---|---|
| user.id | string | Unique user identifier |
| user.email | string | User's email address |
| user.name | string | User's name |
| user.phone_number | string | User's phone number |
| user.third_party_id | string | Third-party system user identifier |
Refund History
Each item in the refund_history array contains:
| Field | Type | Description |
|---|---|---|
| amount | integer | Refunded amount |
| refunded_at | string | Timestamp of this refund |
| reason | string | Reason provided for refund |
The refund_history field is an array of objects or null. Each object in the array represents a refund transaction and contains the following properties:
amount: An integer representing the refunded amount.refunded_at: A string containing the timestamp of the refund in the format "YYYY-MM-DD HH:MM:SS +HHMM".reason: A string explaining the reason for the refund.
Payment Method Details
| Field | Type | Description |
|---|---|---|
| payment_method_details.last_four | string or null | Last four digits of credit card (if applicable) |
| payment_method_details.brand | string or null | Credit card brand (if applicable) |
The brand field can have the following values:
visa: Visa credit/debit cardmastercard: Mastercard credit/debit cardjcb: JCB credit cardunionpay: UnionPay cardamex: American Express carddinersclub: Diners Club carddiscover: Discover cardunknown: Card brand could not be determined
Line Items
Each item in the lineitems array contains:
| Field | Type | Description |
|---|---|---|
| name | string | Item name |
| quantity | integer | Quantity purchased |
| amount | integer | Original amount for this item |
| refunded_amount | integer | Refunded amount for this item |
| item_type | string | Item type (CurriculumPlan, Ticket, MembershipPlan, DigitalProduct, OrderBump) |
| item_id | string | Unique item identifier |
| item_slug | string | URL-friendly item identifier |
| product_type | string | Product type (Course, Event, MembershipPlan, DigitalProduct) |
| product_id | string | Unique product identifier |
| order_bump_details | object or null | Additional details for OrderBump items (only present when item_type is "OrderBump") |
| metadata | object or null | Custom metadata key-value pairs for this item (only present when the External Metadata feature is enabled) |
When item_type is "OrderBump", the order_bump_details field will be present with the following structure:
| Field | Type | Description |
|---|---|---|
| item_type | string | Type of the order bump item (e.g., "CurriculumPlan") |
| item_id | string | Unique identifier of the order bump item |
| item_slug | string | URL-friendly identifier of the order bump item |
If item_type is not "OrderBump", the order_bump_details field will not be present in the lineitem.
The metadata field is a flat object of string key-value pairs. It is only present when your school has the External Metadata feature enabled and the item has metadata defined. Plan-level metadata takes precedence over product-level metadata when keys conflict.
Additional Information
| Field | Type | Description |
|---|---|---|
| coupon | object or null | Applied coupon details |
| shipping_address | object | Shipping address information |
| invoice | object | Invoice details |
| custom_data | array of objects | Custom data fields |
| refund_history | array of objects or null | History of refunds (if any) |
For detailed descriptions of fields within nested objects (coupon, shipping_address, invoice, custom_data, refund_history), please refer to the full documentation.
Invoice Details
| Field | Type | Description |
|---|---|---|
| state | string | Invoice state (e.g., "issued") |
| number | string | Invoice number |
| buyer_ubn | string | Buyer's Unified Business Number (null for individual buyers) |
| buyer_name | string | Name of the buyer |
| category | string | Invoice category (b2b or b2c) |
| carrier_type | string | Type of carrier for e-invoice (member, certificate, or mobile) |
| carrier_num | string | Carrier number for e-invoice (when applicable) |
| donation | boolean | Indicates if the invoice is for donation (only for b2c) |
| love_code | string | Donation institution code (only present when donation is true) |
Notes:
- The
categoryfield can be either "b2b" (business-to-business) or "b2c" (business-to-consumer). - The
carrier_numfield is only present whencarrier_typeis "certificate" or "mobile". - The
donationfield is only applicable whencategoryis "b2c". - The
love_codefield is only present whendonationis true.
Example Payload
{
"type": "payment.refund",
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"user": {
"id": "00f7407f-219e-4ada-9390-28934d7398d5",
"email": "demo@kaik.io",
"name": "Kaik",
"phone_number": "+886911222333",
"third_party_id": "123123"
},
"trade_no": "DEM2022053167602AF30",
"currency": "TWD",
"amount": 1450,
"paid_at": "2022-05-31T11:28:31Z",
"created_at": "2022-05-31T11:26:42Z",
"refunded_at": "2022-06-01T14:30:00Z",
"refunded_amount": 350,
"original_amount": 1800,
"payment_state": "refunded",
"payment_type": "credit",
"payment_method_details": {
"last_four": "1234",
"brand": "visa"
},
"affiliate_code": "newswebPAGE7",
"remark": "Order note",
"lineitems": [
{
"name": "Course Name 123",
"quantity": 1,
"amount": 400,
"refunded_amount": 100,
"item_type": "CurriculumPlan",
"item_id": "51e07cb8-e450-4ed4-8b54-e0144d4da793",
"item_slug": "test-slug",
"product_type": "Course",
"product_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"metadata": {
"crm_id": "sample-crm_id",
"source": "sample-source"
}
},
{
"name": "Course Name",
"quantity": 1,
"amount": 800,
"refunded_amount": 200,
"item_type": "CurriculumPlan",
"item_id": "f8a7b6c5-d4e3-2f1g-9h8i-7j6k5l4m3n2o",
"item_slug": "test-slug",
"product_type": "Course",
"product_id": "a1b2c3d4-e5f6-7890-1234-567890abcdef"
},
{
"name": "Course Bonus Package",
"quantity": 1,
"amount": 250,
"refunded_amount": 50,
"item_type": "OrderBump",
"item_id": "c5d6e7f8-g9h0-i1j2-k3l4-m5n6o7p8q9r0",
"item_slug": "course-bonus-package",
"product_type": "Course",
"product_id": "s1t2u3v4-w5x6-y7z8-9a0b-c1d2e3f4g5h6",
"order_bump_details": {
"item_type": "CurriculumPlan",
"item_id": "h8i9j0k1-l2m3-n4o5-p6q7-r8s9t0u1v2w3",
"item_slug": "course-bonus-package"
}
}
],
"refund_history": [
{
"amount": 350,
"refunded_at": "2022-06-01T14:30:00Z",
"reason": "Partial refund requested by customer"
}
],
"coupon": {
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"name": "30% Off",
"code": "30p-OFF"
},
"shipping_address": {
"city": "Taipei",
"district": "Songshan District",
"postal_code": "105065",
"address": "xxxxx",
"full_address": "105065 Taipei City, Songshan District, xxx"
},
"invoice": {
"state": "issued",
"number": "BL90912974",
"buyer_ubn": null,
"buyer_name": "Kaik Demo",
"category": "b2c",
"carrier_type": "mobile",
"carrier_num": "/0000001",
"donation": false,
"love_code": null
},
"custom_data": [
{
"field_id": "xxxxxx",
"label": "Field One Name",
"type": "multi_select",
"values": ["A", "B"],
"position": 0
},
{
"field_id": "xxxxxx",
"label": "Field Two Name",
"type": "radio",
"values": ["1"],
"position": 1
},
{
"field_id": "xxxxxx",
"label": "Field Three Name",
"type": "text",
"values": ["xxxxx"],
"position": 2
}
]
}
}