create_payment_intent
Initiate payment processing by generating a payment intent for Malaysian transactions through Bayarcash, requiring order details, amount, and payer information.
Instructions
Create a new payment intent for processing payments through Bayarcash. Returns payment intent ID in response. WORKFLOW: 1) If user did not provide payer_email, call list_transactions (per_page=1) to get latest email and ask: "Use email from last payment: {email}?" 2) If user did not provide portal_key, call get_portals and ask user to select. 3) If user did not specify payment channel, call get_payment_channels and ask user to select. 4) Ask if they want to provide phone number (optional). IMPORTANT: Store the returned "id" field (e.g., pi_pGwAaq) to check payment status later.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| order_number | Yes | Unique order number for this payment | |
| amount | Yes | Payment amount in MYR (e.g., 100.50) | |
| payer_email | Yes | Email address of the payer. If not provided, get latest transaction email and ask user if they want to use it. | |
| payer_name | Yes | Name of the payer | |
| description | Yes | Description of the payment | |
| portal_key | Yes | Portal key selected by user from get_portals list | |
| payment_channel | No | Payment channel ID selected by user from get_payment_channels list. Examples: 1=FPX, 2=DuitNow, 3=Boost, 4=GrabPay. | |
| payer_telephone_number | No | Payer phone number (integer, Malaysia numbers only). Ask user: "Would you like to provide a phone number?" Format: 60123456789 |
Implementation Reference
- src/bayarcash-client.ts:264-271 (handler)Core handler function that executes the API call to create a payment intent via POST to /payment-intents endpoint.async createPaymentIntent(intent: PaymentIntentRequest): Promise<PaymentIntentResponse> { try { const response = await this.axiosInstance.post('/payment-intents', intent); return response.data; } catch (error) { this.handleError(error); } }
- src/validation.ts:50-59 (schema)Zod schema for validating input parameters to create_payment_intent tool.export const createPaymentIntentSchema = z.object({ order_number: z.string().min(1, 'Order number is required'), amount: amountSchema, payer_email: emailSchema, payer_name: z.string().min(1, 'Payer name is required'), description: z.string().min(1, 'Description is required'), portal_key: z.string().min(1, 'Portal key is required'), payment_channel: paymentChannelSchema.optional(), payer_telephone_number: phoneSchema.optional() });
- src/index.ts:61-101 (registration)MCP tool registration in list_tools handler, defining name, description, and inputSchema.name: 'create_payment_intent', description: 'Create a new payment intent for processing payments through Bayarcash. Returns payment intent ID in response. WORKFLOW: 1) If user did not provide payer_email, call list_transactions (per_page=1) to get latest email and ask: "Use email from last payment: {email}?" 2) If user did not provide portal_key, call get_portals and ask user to select. 3) If user did not specify payment channel, call get_payment_channels and ask user to select. 4) Ask if they want to provide phone number (optional). IMPORTANT: Store the returned "id" field (e.g., pi_pGwAaq) to check payment status later.', inputSchema: { type: 'object', properties: { order_number: { type: 'string', description: 'Unique order number for this payment' }, amount: { type: 'number', description: 'Payment amount in MYR (e.g., 100.50)' }, payer_email: { type: 'string', description: 'Email address of the payer. If not provided, get latest transaction email and ask user if they want to use it.' }, payer_name: { type: 'string', description: 'Name of the payer' }, description: { type: 'string', description: 'Description of the payment' }, portal_key: { type: 'string', description: 'Portal key selected by user from get_portals list' }, payment_channel: { type: 'number', description: 'Payment channel ID selected by user from get_payment_channels list. Examples: 1=FPX, 2=DuitNow, 3=Boost, 4=GrabPay.' }, payer_telephone_number: { type: 'number', description: 'Payer phone number (integer, Malaysia numbers only). Ask user: "Would you like to provide a phone number?" Format: 60123456789' } }, required: ['order_number', 'amount', 'payer_email', 'payer_name', 'description', 'portal_key'] } },
- src/index.ts:224-240 (handler)MCP call_tool dispatcher case that validates input using schema and delegates to bayarcash client handler.case 'create_payment_intent': { // Validate input const validation = validateInput(createPaymentIntentSchema, args); if (!validation.success) { throw new McpError(ErrorCode.InvalidParams, `Validation error: ${validation.error}`); } const result = await bayarcash.createPaymentIntent(validation.data); return { content: [ { type: 'text', text: JSON.stringify(result, null, 2) } ] }; }
- src/smithery.ts:29-57 (registration)Alternative Smithery framework tool registration with inline schema and handler.server.tool( 'create_payment_intent', 'Create a new payment intent for processing payments through Bayarcash. Returns payment URL and order details with payment intent ID. WORKFLOW: 1) If user has NOT provided payer_email, call list_transactions (limit 1, sorted by latest) to get the most recent payer_email and ask user: "Would you like to use the email from your last payment: {email}?" If yes, use it. If no or no previous transactions, ask for email. 2) If user has NOT provided portal_key, call get_portals first to show list and ask user to select. 3) If user has NOT specified payment_channel, call get_payment_channels to show list and ask user to select. 4) Ask user if they want to provide payer telephone number (optional, Malaysia numbers only). 5) If user already provided these values in their message, use them directly. IMPORTANT: After creating payment, store the returned "id" field (e.g., pi_pGwAaq) - this can be used later to check payment status with get_payment_intent tool.', { order_number: z.string().describe('Unique order number for this payment. Must be unique across all transactions. Example: ORD-001'), amount: z.number().positive().describe('Payment amount in Malaysian Ringgit (MYR). Must be positive. Example: 100.50 for RM100.50'), payer_email: z.string().email().describe('Valid email address of the payer. If user did not provide email: 1) Call list_transactions with per_page=1 to get latest transaction, 2) Extract payer_email from response, 3) Ask user: "Would you like to use the email from your last payment: {email}?" If yes use it, if no ask for new email.'), payer_name: z.string().min(1).describe('Full name of the payer. Required for transaction records.'), description: z.string().min(1).describe('Description of what the payment is for. Shown to customer during payment.'), portal_key: z.string().describe('Portal key from the portal selected by user. Get this from get_portals API call.'), payment_channel: z.number().int().positive().default(1).optional().describe('Payment channel ID (integer). Get this from user selection after showing get_payment_channels list. Examples: 1=FPX, 2=DuitNow, 3=Boost, 4=GrabPay, 5=TNG, 6=ShopeePay.'), payer_telephone_number: z.number().int().positive().optional().describe('Payer phone number (integer, Malaysia numbers only). Ask user: "Would you like to provide a phone number?" If yes, collect the number in format 60123456789 (without spaces or dashes). If no, skip this field.') }, async ({ order_number, amount, payer_email, payer_name, description, portal_key, payment_channel, payer_telephone_number }) => { const result = await bayarcash.createPaymentIntent({ order_number, amount, payer_email, payer_name, description, portal_key, payment_channel, payer_telephone_number }); return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }; } );