API catalog
Browse every verified API method by payment gateway.
This page lists only externally callable APIs that can be mapped to route, controller and driver code. Expand each gateway to view endpoints, parameters, gateway_credentials, responses, errors and test examples.
API CATALOG
PayCore public API catalog
This page provides PayCore integration flows, field definitions, request examples, response formats and payment notification specifications.
Quickstart
Register and verify your email first, then create a PayCore API key from the member portal. Registration never creates a key automatically. After obtaining a key, choose Direct Gateway or an All-in-One project and call the create-payment API.
Create a PayCore account · Open the member portal
API authentication
PayCore APIs authenticate callers with the X-API-KEY header. The complete key is shown once and must remain on the server. Direct Gateway requests carry provider credentials in gateway_credentials, while PayCore AIO always resolves encrypted credentials from the configuration assigned to the API Key and does not accept client overrides.
Integration modes
Direct Gateway lets merchants pass gateway credentials directly. All-in-One projects use a PayCore project API key to manage payment pages and methods centrally.
Payment result notification (Webhook / PayOK)
Payment notifications have two directions: the upstream gateway calls its fixed PayCore callback URL; after PayCore validates and updates the payment, PayCore notifies the merchant-defined payok_url from that create-payment request. payok_url is a per-payment HTTPS receiver, not a fixed PayCore API.
This chapter is the complete merchant integration contract shared by AIO and all Direct Gateways. Merchants do not need and must not call the provider-only /api/paycore/webhooks/{gateway}; that path is only for upstream gateways to notify PayCore.
1. Configure the destination
For every AIO or Direct Gateway payment, set the merchant HTTPS receiver for that transaction in payok_url. Different payments may use different URLs. PayCore makes no delivery when payok_url is omitted.
{
"merchant_order_no": "ORDER202608310001",
"amount": 2250,
"currency": "TWD",
"item_name": "PayCore test product",
"payok_url": "https://merchant.example.com/webhooks/paycore",
"success_url": "https://merchant.example.com/payment/success",
"cancel_url": "https://merchant.example.com/payment/cancel"
}- success_url and cancel_url are browser destinations only and are not proof of payment.
- Fulfil only after a verified PayCore webhook or a payment query returning status=paid.
- payok_url must be a publicly reachable HTTPS hostname. IPv4/IPv6 literals, localhost, loopback, private, and reserved IP targets are rejected.
2. Callback Secret and notification headers
Each PayCore API Key has its own Callback Secret. Generate and store it securely from API Key management, then use it to verify PayCore signatures.
- Keep the Callback Secret on the merchant server only; never expose it in JavaScript, browsers, apps, public source, or logs.
- The Callback Secret is not X-API-KEY and is not provider gateway_credentials.
- After rotating the Callback Secret, the old secret becomes invalid immediately and the receiver must be updated.
POST /webhooks/paycore HTTP/1.1
Content-Type: application/json
X-PayCore-Event-Id: evt_20260831080530ABCDEFGH
X-PayCore-Timestamp: 1788134730
X-PayCore-Signature: v1=4d7f...X-PayCore-Event-Id:Unique event identifier used for idempotency.X-PayCore-Timestamp:Unix timestamp when PayCore generated the notification.X-PayCore-Signature:HMAC-SHA256 signature calculated with the Callback Secret.
3. payment.paid payload
PayCore sends payment.paid after confirming payment. AIO preserves the public master payment, while Direct Gateway uses the actual gateway and method.
PayCore AIO
{
"event_id": "evt_20260831080530ABCDEFGH",
"event_type": "payment.paid",
"payment_no": "PAY20260831080000ABCDEFGH",
"merchant_order_no": "ORDER202608310001",
"gateway": "paycore",
"method": "aio",
"amount": 2250,
"currency": "twd",
"status": "paid",
"paid_at": "2026-08-31T08:05:30+08:00"
}Direct Gateway
{
"event_id": "evt_20260831081530DIRECT01",
"event_type": "payment.paid",
"payment_no": "PAY20260831081000DIRECT01",
"merchant_order_no": "ORDER202608310002",
"gateway": "ecpay",
"method": "credit",
"amount": 980,
"currency": "twd",
"status": "paid",
"paid_at": "2026-08-31T08:15:30+08:00"
}event_id:Unique event identifier; it remains unchanged during retries.event_type:The current successful-payment event is payment.paid.payment_no:Public PayCore payment number.merchant_order_no:Merchant order number supplied when creating payment.gateway、method:AIO uses paycore/aio; Direct uses the actual gateway and method.amount、currency:Must be checked against the merchant order.status:Only paid means PayCore has confirmed payment.paid_at:ISO-8601 payment completion time including timezone.
4. Signature verification and Laravel example
Use the exact raw request body for signature verification. Do not parse, reorder, or re-encode JSON first. In production, reject notifications more than five minutes away from the current time and use hash_equals for constant-time comparison.
signed_payload = X-PayCore-Timestamp + "." + raw_request_body
expected_signature = "v1=" + HMAC-SHA256(signed_payload, callback_secret)Store the Callback Secret in the merchant Laravel environment and read it through config/services.php; never hard-code it in application code.
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
Route::post('/webhooks/paycore', function (Request $request) {
$rawBody = $request->getContent();
$timestamp = (string) $request->header('X-PayCore-Timestamp', '');
$eventId = (string) $request->header('X-PayCore-Event-Id', '');
$received = (string) $request->header('X-PayCore-Signature', '');
$secret = (string) config('services.paycore.callback_secret');
if (! ctype_digit($timestamp) || abs(time() - (int) $timestamp) > 300) {
return response('Invalid timestamp', 401);
}
$expected = 'v1=' . hash_hmac(
'sha256',
$timestamp . '.' . $rawBody,
$secret
);
if ($eventId === '' || ! hash_equals($expected, $received)) {
return response('Invalid signature', 401);
}
$payload = json_decode($rawBody, true, 512, JSON_THROW_ON_ERROR);
if (($payload['event_id'] ?? null) !== $eventId) {
return response('Event ID mismatch', 422);
}
if (($payload['event_type'] ?? null) !== 'payment.paid'
|| ($payload['status'] ?? null) !== 'paid') {
return response('Unsupported event', 422);
}
// Enforce idempotency with a UNIQUE event_id, verify the order and amount,
// then commit the merchant transaction before returning HTTP 2xx.
return response('OK', 200);
});5. Response, retries, and idempotency
Return any HTTP 2xx only after signature verification and the merchant transaction complete. PayCore determines delivery success from the HTTP status only; the response body does not require a fixed JSON format.
HTTP/1.1 200 OK
Content-Type: text/plain
OKFor non-2xx responses, connection failures, or timeouts, PayCore makes up to five total delivery attempts by default:
- Immediately after payment succeeds.
- One minute after the first failure.
- Five minutes after the second failure.
- Fifteen minutes after the third failure.
- Sixty minutes after the fourth failure for the final attempt.
event_id remains unchanged across retries. Enforce a UNIQUE event_id or equivalent idempotency lock to prevent duplicate fulfilment.
6. Merchant processing order and common mistakes
- Preserve the raw request body.
- Validate the timestamp tolerance.
- Verify the HMAC using the Callback Secret for the API Key that created the payment.
- Compare header and body event_id values and enforce idempotency by event_id.
- Verify payment_no, merchant_order_no, amount, currency, and status=paid.
- When needed, call GET /api/paycore/payments/{paymentNo} to confirm status again.
- Return HTTP 2xx only after completing the merchant transaction.
Common mistakes
- Verifying re-encoded JSON instead of the raw body, causing signature mismatch.
- Using X-API-KEY, a provider HashKey, or gateway_credentials as the Callback Secret.
- Failing to verify the amount and merchant order number after receiving payment.paid.
- Treating a success_url browser return as proof of payment.
- Not enforcing idempotency by event_id and processing retries more than once.
- Returning HTTP 200 before the internal transaction completes, preventing retries after a later failure.
PayCore field dictionary and gateway mapping
Names use the original PayCore public API fields. payer_ip, api_request_ip, payment_page_first_ip and provider_callback_first_ip represent different sources. The payment-page IP is recorded on the first valid payment-page visit; the gateway callback IP is recorded after notification validation. These IPs identify network sources and do not prove payer identity. When no dedicated gateway field exists, data remains in PayCore or is written to an allowed Remark/Metadata field.
Create-payment request
| Field | Source | Type | Required | Description | Example |
|---|---|---|---|---|---|
merchant_order_no |
API body | string|max:100 |
Yes | Merchant order number; keep it unique under the same API key. | ORDER202607130001 |
amount |
API body | integer|min:1 |
Yes | Payment amount; unit and currency constraints depend on the gateway. | 980 |
currency |
API body | string|max:10 |
No | Currency code such as TWD or USD. | TWD |
payer_account |
API body | string|max:100 |
No | Payer/member identifier in the merchant system; not an identity number. | member-001 |
payer_identity_no |
API body | string|max:80 |
No | Payer identity number; sent only to gateways with a confirmed matching field. | A123456789 |
payer_ip |
API body | IPv4|IPv6 |
No | Actual payer/order-context IP supplied by the API integrator. | 203.0.113.20 |
success_url |
API body | URL |
No | Merchant URL used after successful payment. | https://merchant.example/success |
return_url |
API body | URL |
No | Compatibility return URL; some gateways use it when success_url is omitted. | https://merchant.example/return |
cancel_url |
API body | URL |
No | Merchant URL used after cancellation or incomplete payment. | https://merchant.example/cancel |
payok_url |
API body | HTTPS hostname URL |
No | Merchant URL notified by PayCore after payment is confirmed. Each request may choose a hostname URL; IP literals are rejected. | https://merchant.example/payok |
locale |
API body | string|max:20 |
No | Preferred locale for the payment page. | zh-tw |
item_name |
API body | string|max:200 |
No | Item name; safely limited to the gateway constraint. | 測試商品 |
description |
API body | string|max:200 |
No | Payment description; some gateways use it as the item name when item_name is omitted. | 訂單付款 |
payer_name |
API body | string|max:100 |
No | Payer name; directly sent only when an official mapping exists. | 王小明 |
payer_mobile |
API body | string|max:30 |
No | Payer mobile number. | 0912345678 |
payer_tel |
API body | string|max:30 |
No | Payer telephone or landline. | 02-12345678 |
payer_email |
API body | email|max:150 |
No | Payer email. | [email protected] |
merchant_custom_field_1 |
API body | string|max:200 |
No | Merchant custom field 1; mapped only to officially supported fields. | campaign-A |
merchant_custom_field_2 |
API body | string|max:200 |
No | Merchant custom field 2; mapped only to officially supported fields. | note-B |
credit_installment |
API body | integer|0,3,6,12,18,24,30 |
No | Card installment count; currently used only by GoMyPay credit. Use 0 or omit for a normal transaction. | 0 |
expire_days |
API body | integer|1..60 |
No | Expiration days for offline payment. | 7 |
expire_minutes |
API body | integer|60..43200 |
No | Expiration minutes for offline payment; generally takes precedence over expire_days. | 1440 |
cvs_type |
API body | enum |
No | Convenience-store type. Accepted values depend on the gateway. | ibon |
bank_code |
API body | string|max:10 |
No | Generic bank-code field for ECPay background ATM. | 007 |
atm_bank_code |
API body | string|max:10 |
No | Compatibility bank-code name for ECPay background ATM. | 007 |
ecpay_atm_bank_code |
API body | string|max:10 |
No | ECPay-specific bank-code name for background ATM. | 007 |
cvs_code |
API body | enum |
No | Generic store-code field for ECPay background CVS. | FAMILY |
ecpay_cvs_code |
API body | enum |
No | ECPay-specific store-code name for background CVS. | FAMILY |
desc_1 |
API body | string|max:20 |
No | ECPay background-payment description field 1. | |
desc_2 |
API body | string|max:20 |
No | ECPay background-payment description field 2. | |
desc_3 |
API body | string|max:20 |
No | ECPay background-payment description field 3. | |
desc_4 |
API body | string|max:20 |
No | ECPay background-payment description field 4. | |
gateway_credentials |
API body | object |
Yes | Gateway merchant credentials; see each endpoint for child fields. Never copy them to remarks or metadata. | {...} |
PayCore-generated fields
| Field | Source | Type | Required | Description | Example |
|---|---|---|---|---|---|
api_request_ip |
PayCore | IPv4|IPv6|null |
No | Caller IP observed automatically by PayCore when the API order is created; integrators cannot override it. | 198.51.100.10 |
payment_page_first_ip |
PayCore | IPv4|IPv6|null |
No | Source IP observed on the first valid-token HTML visit to a PayCore show, processing, or result page. It does not prove a verified human identity. | 203.0.113.30 |
payment_page_first_seen_at |
PayCore | datetime|null |
No | Timestamp atomically recorded with payment_page_first_ip. Refreshes and status polling do not overwrite it. | 2026-07-13T10:30:00+08:00 |
provider_callback_first_ip |
PayCore | IPv4|IPv6|null |
No | Source IP of the first verified server callback from a gateway to PayCore. Browser returns, outbound PayOK notifications, and rejected callbacks are excluded. | 192.0.2.40 |
provider_callback_first_seen_at |
PayCore | datetime|null |
No | Timestamp atomically recorded with provider_callback_first_ip. Gateway retries do not overwrite it. | 2026-07-13T10:35:00+08:00 |
payment_no |
PayCore | string |
Yes | PayCore payment number. | PAY202607130001ABCDEFGH |
gateway |
URL / PayCore | string |
Yes | Gateway key such as stripe, plus, pfun, gomypay, or funpoint. | stripe |
method |
URL / PayCore | string |
Yes | Payment-method key under the gateway. | credit |
api_key_id |
PayCore | integer |
Yes | Read-only relation resolved automatically from X-API-KEY; not accepted from the API body. | |
preferred_locale |
PayCore | string|null |
No | Normalized payment-page locale derived from locale or Accept-Language. | zh-tw |
Common response
| Field | Source | Type | Required | Description | Example |
|---|---|---|---|---|---|
success |
API response | boolean |
Yes | Whether the API request succeeded. | true |
message |
API response | string |
Yes | Human-readable result message. | Payment created successfully |
data.payment_no |
API response | string |
Yes | PayCore payment number. | |
data.merchant_order_no |
API response | string |
Yes | Merchant order number. | |
data.gateway |
API response | string |
Yes | Gateway key. | |
data.method |
API response | string |
Yes | Payment-method key. | |
data.amount |
API response | integer |
Yes | Payment amount. | |
data.currency |
API response | string |
Yes | Payment currency. | |
data.status |
API response | string |
Yes | PayCore payment status. | pending |
data.payment_method |
API response | string|null |
No | PayCore payment-flow classification. | |
data.payment_url |
API response | URL|null |
No | PayCore payment page or gateway redirect URL. | |
data.payment_info |
API response | object |
No | Gateway payment instructions or frontend initialization data; content varies by gateway. | |
data.created |
API response | boolean |
No | Whether this call created a new transaction; false when an existing active payment is returned. | |
data.paid_at |
API response | datetime|null |
No | Time when PayCore confirmed payment success. | |
data.created_at |
API response | datetime|null |
No | PayCore transaction creation time. | |
error |
API response | object|string|null |
No | Error code, validation fields, or context returned on failure. | |
Gateway field mappings
Stored in PayCore means the value remains in the PayCore transaction record and is not sent to that gateway. Fallback fields are used only when the primary mapped value is unavailable.
| PayCore field | ECPay | SmilePay | Stripe | PayPal | PLUS | PFun | Junding Technology GoMyPay | FunPoint |
|---|---|---|---|---|---|---|---|---|
api_request_ip |
Stored in PayCore | Remark | metadata.api_request_ip | Stored in PayCore | Stored in PayCore | ClientIP fallback; payer_ip is also written to Remark | Buyer_Memo fallback | Remark fallback |
payer_ip |
Stored in PayCore | Remark | metadata.payer_ip | Stored in PayCore | Stored in PayCore | ClientIP (primary) | Buyer_Memo fallback | Remark fallback |
payment_page_first_ip |
Stored in PayCore | Stored in PayCore | Stored in PayCore | Stored in PayCore | Stored in PayCore | Stored in PayCore | Stored in PayCore | Stored in PayCore |
provider_callback_first_ip |
verified callback source | verified callback source | verified signature source | verified webhook source | verified callback source | validated callback source | verified str_check source | verified CheckMacValue source |
payer_account |
Stored in PayCore | Pur_name fallback | metadata.payer_account | Stored in PayCore | Used to build payName | Stored in PayCore | Buyer_Memo fallback | Remark fallback |
payer_name |
Stored in PayCore | Pur_name | Stored in PayCore | Stored in PayCore | Stored in PayCore | ReceiverName | Buyer_Name | Remark fallback |
payer_mobile |
Stored in PayCore | Mobile_number | Stored in PayCore | Stored in PayCore | Stored in PayCore | ReceiverTel (primary) | Buyer_Telm (primary) | Remark fallback |
payer_tel |
Stored in PayCore | Tel_number | Stored in PayCore | Stored in PayCore | Stored in PayCore | ReceiverTel fallback | Buyer_Telm fallback | Remark fallback |
payer_email |
Stored in PayCore | receipt_email | Stored in PayCore | Stored in PayCore | ReceiverEmail | Buyer_Mail | Remark fallback | |
payer_identity_no |
Stored in PayCore | Stored in PayCore | Stored in PayCore | Stored in PayCore | Stored in PayCore | ReceiverID | Stored in PayCore | Stored in PayCore |
item_name |
ItemName | Od_sob | PaymentIntent description fallback | purchase item name | Stored in PayCore | TradeTitle | Buyer_Memo fallback | ItemName |
description |
TradeDesc / ItemName fallback | Od_sob fallback | PaymentIntent.description | purchase description | Stored in PayCore | OrderInfo / TradeTitle fallback | Buyer_Memo | TradeDesc / ItemName fallback |
merchant_custom_field_1 |
Stored in PayCore | Stored in PayCore | Stored in PayCore | Stored in PayCore | Stored in PayCore | CustomField1 | Buyer_Memo fallback | CustomField1 |
merchant_custom_field_2 |
Stored in PayCore | Stored in PayCore | Stored in PayCore | Stored in PayCore | Stored in PayCore | CustomField2 | Buyer_Memo fallback | CustomField2 |
credit_installment |
Stored in PayCore | Stored in PayCore | Stored in PayCore | Stored in PayCore | Stored in PayCore | Stored in PayCore | TransMode / Installment | Stored in PayCore |
Choose an API from the left to view details
To keep /developer/api fast, this page loads the catalog index first; full parameter tables and examples are loaded by AJAX only after an endpoint is selected.
Pico is here with you at the end.
Need to find another API, return to the catalog, or review the integration flow? Jump back to search or continue from the API catalog.