πŸ”ESC
Type to start searching...
πŸ‘€Owner: Reliva
πŸ•’Last updated:

Overview#

MelakaPay now exposes another generic payment entry points:

  1. External API Controller (/generic/*) β€” a JSON API for external systems to initiate payments, receive responses, requery transactions, view receipts, and download PDFs.

Base URLs#

Staging: https://melakapaystg.melaka.gov.my Production: https://melakapay.melaka.gov.my

Authentication#

  • API / external payments: merchant_code (request body or X-Merchant-Code header) and api_key (Bearer token or api_key body parameter). The /generic/* API routes are excluded from CSRF validation so they can be called by external systems.

    Merchants and their API keys are registered in config/generic.php:

    php
    'cmi-zoo' => [
        'name' => 'Zoo Melaka',
        'id' => 26,
        'api_keys' => [
            env('GENERIC_MERCHANT_CMI_ZOO_KEY', 'a08ec971b56d3c85d4026b58abf9088398346552760525019b988a0a8726959a'),
        ],
    ],

Endpoints Summary#

EndpointMethodDescription
`/generic/check`GETValidate merchant credentials and API connectivity
`/generic/request`POSTInitiate a payment from an external system
`/generic/response`POSTPayment gateway response handler (internal)
`/generic/receipt/{id}`GETView payment receipt by transaction ID
`/generic/requery/{transaksi_id}`GETRequery a transaction status from EPIC
`/generic/download/{id}`GETDownload receipt/statement PDF
`/generic/debug`GETDebug page to simulate a payment response
`/generic/simulate`GETSimulate page to test `/generic/request`

1. Check Connectivity#

Validates the supplied merchant_code and API key.

Endpoint: GET /generic/check

Headers#

HeaderValueRequired
`Authorization``Bearer `Yes
`X-Merchant-Code```Alternative to body
`Content-Type``application/json`No

Request Body#

FieldTypeRequiredDescription
`merchant_code`string**Yes**Agency merchant code
`api_key`string**Yes**API key (if not using Bearer token)

Example#

bash
curl -X GET https://melakapaystg.melaka.gov.my/generic/check \
  -H "Authorization: Bearer <API_KEY>" \
  -H "X-Merchant-Code: cmi-zoo"

Response#

json
{
  "status": true,
  "message": "Connection successful",
  "data": {
    "merchant_code": "cmi-zoo",
    "timestamp": "2026-07-24T16:00:00+08:00",
    "environment": "local"
  }
}

Error Responses#

HTTP CodeResponse
401{ "status": false, "message": "Missing merchant_code or API key" }
401{ "status": false, "message": "Merchant code not registered" }
401{ "status": false, "message": "Unauthorized - invalid API key for merchant" }

2. Initiate API Payment#

Starts a generic payment session. The response is an HTML payment page that the payer completes in a browser.

Endpoint: POST /generic/request

Headers#

HeaderValueRequired
`Authorization``Bearer `Yes
`Content-Type``application/json`Yes
`X-Merchant-Code```Alternative to body

Request Body#

FieldTypeRequiredDescription
`merchant_code`string**Yes**Agency merchant code
`trans_id`string**Yes**External transaction reference
`amount`numeric**Yes**Total payment amount in RM
`service`string**Yes**Service name shown to the payer
`description`string**Yes**Payment description
`callback_url`url**Yes**URL that receives the payment result
`redirect_url`url**Yes**URL to redirect the payer after payment
`name`stringNoPayer name
`email`emailNoPayer email for receipt delivery
`ic_no`stringNoPayer IC / username
`address_1`stringNoAddress line 1
`address_2`stringNoAddress line 2
`city`stringNoCity
`postcode`stringNoPostcode
`state`stringNoState
`phone_no`stringNoPhone number
`extra`objectNoAdditional fields stored in the generic details table

Details Storage#

The system first tries to store request details in an agency-specific table derived from the merchant code (e.g. cmi_details). If that table does not exist, the data is written to generic_details instead. New integrations therefore do not need a dedicated details table.

Example#

bash
curl -X POST https://melakapaystg.melaka.gov.my/generic/request \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <API_KEY>" \
  -d '{
    "merchant_code": "cmi-zoo",
    "trans_id": "ZOO-77-20260815120000",
    "amount": "150.00",
    "service": "Tiket Zoo Melaka",
    "description": "Bayaran tiket masuk Zoo Melaka",
    "callback_url": "https://your-system.example.com/melakapay/callback",
    "redirect_url": "https://your-system.example.com/payment/complete",
    "name": "LUKMANUL HAKIM",
    "email": "email@user.example",
    "ic_no": "920722055401",
    "phone_no": "0135871622",
    "extra": {
      "kod_hasil": "H0272499",
      "caj_bayaran": "150.00",
      "no_permohonan": "BILL-PROC-0056",
      "bill_type": "processing_fee",
      "invoice_no": "BILL-PROC-0056",
      "company_name": "NAMA COMPANY SDN BHD",
      "company_no": "9811223-X"
    }
  }'

Success Response#

Status Code: 200 OK

Returns the MelakaPay payment page HTML. The payer selects a payment method and is redirected to the FPX/payment gateway.

Error Responses#

HTTP CodeResponse
400 / 401`{ "status": false, "message": "Missing merchant_code or API key" }`
400`{ "status": false, "message": "" }`

3. Payment Response (Internal)#

This endpoint is called by the FPX/payment gateway after the payer completes the transaction. It is not called directly by merchants.

Internal Endpoint: POST /generic/response

What Happens#

  1. MelakaPay receives the payment result from the gateway.
  2. The transaction and receipt records are updated.
  3. A callback job is dispatched to the callback_url supplied in the original request.
  4. On success (STATUS = 1), a receipt email job is dispatched if an email was provided.
  5. The gateway/user is redirected to /generic/receipt/{transaction_id}.

Gateway Fields#

FieldDescription
`STATUS``0` = failed, `1` = success, `2` = cancelled, `3` = pending
`PAYMENT_MODE``fpx`, `fpx1`, `cc`, `dnqr`, `wallet`
`MERCHANT_CODE`Merchant code
`TRANS_ID`MelakaPay transaction ID
`RECEIPT_NO`Receipt number
`PAYMENT_TRANS_ID`Gateway transaction ID
`PAYMENT_DATETIME`Transaction date/time
`AMOUNT`Paid amount
`BUYER_BANK`Payer's bank
`BUYER_NAME`Payer's name
`MERCHANT_ORDER_NO`EPS seller order number

4. Requery Transaction#

Queries the EPIC database for a transaction status and updates the local record.

Endpoint: GET /generic/requery/{transaksi_id}

Headers#

HeaderValueRequired
`Authorization``Bearer `Yes
`X-Merchant-Code```Alternative to body

Example#

bash
curl -X GET https://melakapaystg.melaka.gov.my/generic/requery/ZOO-77-20260815120000 \
  -H "Authorization: Bearer <API_KEY>" \
  -H "X-Merchant-Code: cmi-zoo"

Response#

json
{
  "success": true,
  "data": { ... },
  "message": "Successfully get the transaction from EPIC. Update status: success"
}

5. View Receipt#

Displays the receipt page for a completed transaction.

Endpoint: GET /generic/receipt/{id}

Example#

bash
curl -X GET https://melakapaystg.melaka.gov.my/generic/receipt/12345

Response#

HTML receipt page with transaction details and a back-to-merchant button.


6. Download Receipt#

Downloads the receipt or statement PDF for a transaction.

Endpoint: GET /generic/download/{id}

Example#

bash
curl -X GET https://melakapaystg.melaka.gov.my/generic/download/12345 \
  -o MelakaPay-Receipt-12345.pdf

Response#

PDF stream (Content-Type: application/pdf).


7. Debug / Simulate#

These are browser-based testing pages.

EndpointDescription
`GET /generic/debug`Simulate a payment gateway response
`GET /generic/simulate`Build and send a test `/generic/request` payload

8. Callback Notification#

After the payment result is processed, MelakaPay POSTs a payload to the callback_url supplied in the original request.

Callback Payload#

FieldTypeDescription
`transaction_id`stringMelakaPay internal transaction ID
`trans_id`stringOriginal `account_id` / `trans_id` supplied
`status`stringNumeric status: `0` / `1` / `2` / `3`
`payment_status`stringHuman-readable status
`receipt_no`stringReceipt number if successful
`payment_datetime`stringPayment date and time
`buyer_name`stringName of payer
`amount`stringTotal amount paid
`payment_mode`stringPayment method
`fpx_charge`stringFPX transaction fee
`buyer_bank`stringPayer's bank
`fpx_transaction_no`stringFPX reference number
`seller_order_no`stringMelakaPay merchant order number
`merchant_code`stringMerchant code
`description`stringPayment description
`service`stringService name

Example Successful Callback#

json
{
  "transaction_id": "12345",
  "trans_id": "ZOO-77-20260815120000",
  "status": "1",
  "payment_status": "Berjaya",
  "receipt_no": "RCP-001234",
  "payment_datetime": "2026-07-24 15:30:00",
  "buyer_name": "LUKMANUL HAKIM",
  "amount": "150.50",
  "payment_mode": "FPX (Individual)",
  "fpx_charge": "0.50",
  "buyer_bank": "Maybank2u",
  "fpx_transaction_no": "FPX-TXN-99887766",
  "seller_order_no": "EPX-20260724153000",
  "merchant_code": "cmi-zoo",
  "description": "Bayaran tiket masuk Zoo Melaka",
  "service": "Tiket Zoo Melaka"
}

Payment Flow Summary#

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     POST /generic/request         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                  β”‚ ─────────────────────────────────►│              β”‚
β”‚  External System β”‚   (merchant_code + api_key +      β”‚   MelakaPay  β”‚
β”‚                  β”‚   trans_id, amount, callback_url) β”‚              β”‚
β”‚                  β”‚ ◄─────────────────────────────────│              β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   HTML payment page               β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜
                                                              β”‚
                                                              β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚               Payer selects bank / payment method        β”‚
β”‚                  & submits to FPX gateway                β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                                                β”‚
                                                                β–Ό
                                                       β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                                                       β”‚  FPX Gateway β”‚
                                                       β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜
                                                                β”‚
                                                                β–Ό
                                                       β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                                                       β”‚ POST /genericβ”‚
                                                       β”‚  /response   β”‚
                                                       β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜
                                                                β”‚
                                POST callback_url               β”‚
◄───────────────────────────────────────────────────────┬───────┴───────┐
   (payment result payload)                             β–Ό               β–Ό
                                                β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                                                β”‚  Receipt  β”‚  β”‚  Email with  β”‚
                                                β”‚   Page    β”‚  β”‚  PDF Receipt β”‚
                                                β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Files Created/Modified#

FileDescription
`app/Http/Controllers/Payment/GenericPaymentController.php`Portal generic payment processing controller
`app/Http/Controllers/API/GenericAPIController.php`External generic API controller
`config/generic.php`Merchant credentials and agency metadata for API access
`database/migrations/2026_08_15_000001_create_generic_details_table.php`Fallback generic payment details table
`app/Http/Requests/Payment/GenericPaymentRequest.php`Validation rules for portal generic payments
`app/Jobs/PostGenericCallback.php`Job for dispatching external merchant callbacks
`resources/views/user/generic/*.blade.php`Generic payment, receipt, debug, and simulate views
`routes/web.php`Route registration for `/generic/*` and `/payment/process/generic`
`docs/generic-payment-api.md`This documentation
`docs/generic-payment-api.postman_collection.json`Importable Postman collection

Changelog#

Version 1.2.1 (2026-08-17)#

  • Removed unused enpoint

Version 1.2.0 (2026-08-15)#

  • Moved API merchant credential validation from agencies/agency_services to config/generic.php.
  • Added generic_details fallback table for merchants without an agency-specific details table.
  • Updated GenericPaymentController and GenericAPIController to use generic_details as fallback.

Version 1.1.0 (2026-07-24)#

  • Added external generic API controller (GenericAPIController) with /generic/* endpoints.
  • Added credential validation against agencies and agency_services.
  • Added receipt, requery, download, debug, and simulate API endpoints.
  • Added PostGenericCallback job for asynchronous merchant notifications.

Version 1.0.0 (2026-07-24)#

  • Initial generic agency payment controller based on BksaController.
  • Supports agency_id or merchant_code agency resolution.
  • Supports portal (source=portal) and API (source=api) payment flows.
  • Auto-derives agency-specific details table from merchant code.
  • Accepts arbitrary details and fpx_data payloads for agency extensibility.