Skip to content

Create a Payment

Creates a new payment. You can create a payment with an existing payment method or provide payment method details directly.

POST/v1/payments

Parameters

Required Parameters

amount required integer

Amount in smallest currency unit. For MYR, use cents (e.g., 10000 for RM 100.00).

currency required string

Three-letter ISO currency code (e.g., myr, usd, sgd).

Optional Parameters

payment_method optional string

ID of an existing PaymentMethod to use for this payment.

payment_method_data optional object

Payment method details to create a new payment method. See payment_method_data below.

customer optional string

ID of an existing Customer. If provided, the payment method can be saved for future use.

description optional string

An arbitrary string describing the payment.

metadata optional object

Custom key-value pairs (up to 50 pairs).

capture_method optional string

Controls when the funds are captured. Options:

  • automatic (default) - Capture immediately
  • manual - Authorize now, capture later

receipt_email optional string

Email address to send the receipt to.

return_url optional string

URL to redirect the customer to after authentication (required for FPX and 3D Secure).

save_payment_method optional boolean

Set to true to save the payment method for future use. Requires customer to be set.

payment_method_data

Card Payments

json
{
  "type": "card",
  "card": {
    "number": "4242424242424242",
    "exp_month": 12,
    "exp_year": 2025,
    "cvc": "123"
  }
}

Or with a token:

json
{
  "type": "card",
  "card": {
    "token": "tok_xxxxx"
  }
}

FPX Payments

json
{
  "type": "fpx",
  "fpx": {
    "bank_code": "MBBEMYKL"
  }
}

Returns

Returns the Payment object if successful.

Examples

Basic Card Payment

bash
curl https://api.salam.com/v1/payments \
  -H "Authorization: Bearer sk_test_xxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 10000,
    "currency": "myr",
    "payment_method_data": {
      "type": "card",
      "card": {
        "number": "4242424242424242",
        "exp_month": 12,
        "exp_year": 2025,
        "cvc": "123"
      }
    },
    "description": "Order #12345"
  }'
javascript
const payment = await salam.payments.create({
  amount: 10000,
  currency: 'myr',
  payment_method_data: {
    type: 'card',
    card: {
      number: '4242424242424242',
      exp_month: 12,
      exp_year: 2025,
      cvc: '123',
    },
  },
  description: 'Order #12345',
});
php
$payment = $salam->payments->create([
    'amount' => 10000,
    'currency' => 'myr',
    'payment_method_data' => [
        'type' => 'card',
        'card' => [
            'number' => '4242424242424242',
            'exp_month' => 12,
            'exp_year' => 2025,
            'cvc' => '123',
        ],
    ],
    'description' => 'Order #12345',
]);

Payment with Existing Payment Method

javascript
const payment = await salam.payments.create({
  amount: 10000,
  currency: 'myr',
  customer: 'cus_xxxxx',
  payment_method: 'pm_xxxxx',
  description: 'Subscription payment',
});

FPX Payment

javascript
const payment = await salam.payments.create({
  amount: 10000,
  currency: 'myr',
  payment_method_data: {
    type: 'fpx',
    fpx: {
      bank_code: 'MBBEMYKL', // Maybank
    },
  },
  return_url: 'https://yoursite.com/payment/complete',
});

// Redirect customer to complete payment
if (payment.status === 'requires_action') {
  res.redirect(payment.next_action.redirect_to_url);
}

Manual Capture

javascript
// Authorize the payment
const payment = await salam.payments.create({
  amount: 10000,
  currency: 'myr',
  payment_method: 'pm_xxxxx',
  capture_method: 'manual',
});

// Later, capture the payment
await salam.payments.capture(payment.id);

Save Payment Method for Future Use

javascript
const payment = await salam.payments.create({
  amount: 10000,
  currency: 'myr',
  customer: 'cus_xxxxx',
  payment_method_data: {
    type: 'card',
    card: {
      number: '4242424242424242',
      exp_month: 12,
      exp_year: 2025,
      cvc: '123',
    },
  },
  save_payment_method: true,
});

// The payment method is now saved to the customer

Response

json
{
  "id": "pay_1234567890abcdef",
  "object": "payment",
  "amount": 10000,
  "currency": "myr",
  "status": "succeeded",
  "payment_method": "pm_xxxxx",
  "description": "Order #12345",
  "metadata": {},
  "captured": true,
  "refunded": false,
  "refunded_amount": 0,
  "receipt_email": null,
  "receipt_url": "https://pay.salam.com/receipts/pay_xxxxx",
  "client_secret": "pay_xxxxx_secret_xxxxx",
  "next_action": null,
  "last_payment_error": null,
  "created": 1704067200,
  "livemode": false
}

Error Responses

Card Declined

json
{
  "error": {
    "type": "card_error",
    "code": "card_declined",
    "message": "Your card was declined.",
    "decline_code": "generic_decline"
  }
}

Insufficient Funds

json
{
  "error": {
    "type": "card_error",
    "code": "card_declined",
    "message": "Your card has insufficient funds.",
    "decline_code": "insufficient_funds"
  }
}

Invalid Parameters

json
{
  "error": {
    "type": "invalid_request_error",
    "code": "parameter_missing",
    "message": "Missing required parameter: amount",
    "param": "amount"
  }
}

Error Codes

CodeDescription
card_declinedThe card was declined
insufficient_fundsInsufficient funds on the card
expired_cardThe card has expired
incorrect_cvcThe CVC code is incorrect
processing_errorPayment processor error
invalid_numberInvalid card number
invalid_expiry_monthInvalid expiration month
invalid_expiry_yearInvalid expiration year
parameter_missingRequired parameter is missing
payment_method_not_availablePayment method not available

Idempotency

To safely retry payment creation, include an idempotency key:

javascript
const payment = await salam.payments.create({
  amount: 10000,
  currency: 'myr',
  payment_method: 'pm_xxxxx',
}, {
  idempotencyKey: 'unique-key-123',
});

Repeated requests with the same key will return the same payment object.

Released under the MIT License.