paymongo-cli 1.4.3 → 1.4.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,539 @@
1
+ export function getHtmlTemplate() {
2
+ return `<!DOCTYPE html>
3
+ <html lang="en">
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>PayMongo Checkout</title>
8
+ <script src="https://js.paymongo.com/v1/paymongo.js"></script>
9
+ <style>
10
+ body {
11
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
12
+ max-width: 400px;
13
+ margin: 50px auto;
14
+ padding: 20px;
15
+ }
16
+ .checkout-form {
17
+ background: #f9f9f9;
18
+ padding: 20px;
19
+ border-radius: 8px;
20
+ }
21
+ .form-group {
22
+ margin-bottom: 15px;
23
+ }
24
+ label {
25
+ display: block;
26
+ margin-bottom: 5px;
27
+ font-weight: 500;
28
+ }
29
+ input, select {
30
+ width: 100%;
31
+ padding: 10px;
32
+ border: 1px solid #ddd;
33
+ border-radius: 4px;
34
+ font-size: 16px;
35
+ }
36
+ button {
37
+ width: 100%;
38
+ padding: 12px;
39
+ background: #007bff;
40
+ color: white;
41
+ border: none;
42
+ border-radius: 4px;
43
+ font-size: 16px;
44
+ cursor: pointer;
45
+ }
46
+ button:hover {
47
+ background: #0056b3;
48
+ }
49
+ button:disabled {
50
+ background: #ccc;
51
+ cursor: not-allowed;
52
+ }
53
+ </style>
54
+ </head>
55
+ <body>
56
+ <div class="checkout-form">
57
+ <h2>Complete Your Payment</h2>
58
+ <form id="payment-form">
59
+ <div class="form-group">
60
+ <label for="email">Email</label>
61
+ <input type="email" id="email" required>
62
+ </div>
63
+
64
+ <div class="form-group">
65
+ <label for="card-number">Card Number</label>
66
+ <input type="text" id="card-number" placeholder="1234 5678 9012 3456" required>
67
+ </div>
68
+
69
+ <div class="form-group">
70
+ <label for="expiry">Expiry Date</label>
71
+ <input type="text" id="expiry" placeholder="MM/YY" required>
72
+ </div>
73
+
74
+ <div class="form-group">
75
+ <label for="cvc">CVC</label>
76
+ <input type="text" id="cvc" placeholder="123" required>
77
+ </div>
78
+
79
+ <button type="submit" id="pay-button">Pay ₱100.00</button>
80
+ </form>
81
+ </div>
82
+
83
+ <script>
84
+ // Replace with your actual client key from the payment intent
85
+ const clientKey = 'YOUR_CLIENT_KEY_HERE';
86
+
87
+ const paymongo = new Paymongo(clientKey);
88
+
89
+ document.getElementById('payment-form').addEventListener('submit', async (e) => {
90
+ e.preventDefault();
91
+
92
+ const payButton = document.getElementById('pay-button');
93
+ payButton.disabled = true;
94
+ payButton.textContent = 'Processing...';
95
+
96
+ try {
97
+ // Create payment method
98
+ const paymentMethod = await paymongo.createPaymentMethod({
99
+ type: 'card',
100
+ details: {
101
+ card_number: document.getElementById('card-number').value.replace(/\\s/g, ''),
102
+ exp_month: document.getElementById('expiry').value.split('/')[0],
103
+ exp_year: '20' + document.getElementById('expiry').value.split('/')[1],
104
+ cvc: document.getElementById('cvc').value,
105
+ },
106
+ billing: {
107
+ email: document.getElementById('email').value,
108
+ },
109
+ });
110
+
111
+ // Attach payment method to payment intent
112
+ const result = await paymongo.attachPaymentIntent('YOUR_PAYMENT_INTENT_ID', {
113
+ payment_method: paymentMethod.id,
114
+ return_url: window.location.origin + '/success',
115
+ });
116
+
117
+ if (result.next_action) {
118
+ // Handle 3D Secure or other next actions
119
+ window.location.href = result.next_action.redirect.url;
120
+ } else {
121
+ // Payment succeeded
122
+ window.location.href = '/success';
123
+ }
124
+
125
+ } catch (error) {
126
+ console.error('Payment failed:', error);
127
+ alert('Payment failed. Please try again.');
128
+ payButton.disabled = false;
129
+ payButton.textContent = 'Pay ₱100.00';
130
+ }
131
+ });
132
+ </script>
133
+ </body>
134
+ </html>`;
135
+ }
136
+ export function getReactTemplate() {
137
+ return `import React, { useState } from 'react';
138
+
139
+ interface CheckoutFormProps {
140
+ clientKey: string;
141
+ paymentIntentId: string;
142
+ amount: number;
143
+ onSuccess: (result: any) => void;
144
+ onError: (error: any) => void;
145
+ }
146
+
147
+ const CheckoutForm: React.FC<CheckoutFormProps> = ({
148
+ clientKey,
149
+ paymentIntentId,
150
+ amount,
151
+ onSuccess,
152
+ onError
153
+ }) => {
154
+ const [loading, setLoading] = useState(false);
155
+ const [formData, setFormData] = useState({
156
+ email: '',
157
+ cardNumber: '',
158
+ expiry: '',
159
+ cvc: ''
160
+ });
161
+
162
+ const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
163
+ const { name, value } = e.target;
164
+ setFormData(prev => ({
165
+ ...prev,
166
+ [name]: value
167
+ }));
168
+ };
169
+
170
+ const handleSubmit = async (e: React.FormEvent) => {
171
+ e.preventDefault();
172
+ setLoading(true);
173
+
174
+ try {
175
+ // Load PayMongo script dynamically if not already loaded
176
+ if (!window.Paymongo) {
177
+ await new Promise((resolve, reject) => {
178
+ const script = document.createElement('script');
179
+ script.src = 'https://js.paymongo.com/v1/paymongo.js';
180
+ script.onload = resolve;
181
+ script.onerror = reject;
182
+ document.head.appendChild(script);
183
+ });
184
+ }
185
+
186
+ const paymongo = new (window as any).Paymongo(clientKey);
187
+
188
+ // Create payment method
189
+ const paymentMethod = await paymongo.createPaymentMethod({
190
+ type: 'card',
191
+ details: {
192
+ card_number: formData.cardNumber.replace(/\\s/g, ''),
193
+ exp_month: parseInt(formData.expiry.split('/')[0]),
194
+ exp_year: 2000 + parseInt(formData.expiry.split('/')[1]),
195
+ cvc: formData.cvc,
196
+ },
197
+ billing: {
198
+ email: formData.email,
199
+ },
200
+ });
201
+
202
+ // Attach payment method to payment intent
203
+ const result = await paymongo.attachPaymentIntent(paymentIntentId, {
204
+ payment_method: paymentMethod.id,
205
+ return_url: window.location.origin + '/success',
206
+ });
207
+
208
+ onSuccess(result);
209
+
210
+ } catch (error) {
211
+ onError(error);
212
+ } finally {
213
+ setLoading(false);
214
+ }
215
+ };
216
+
217
+ return (
218
+ <div style={{ maxWidth: '400px', margin: '50px auto', padding: '20px' }}>
219
+ <div style={{
220
+ background: '#f9f9f9',
221
+ padding: '20px',
222
+ borderRadius: '8px'
223
+ }}>
224
+ <h2>Complete Your Payment</h2>
225
+ <form onSubmit={handleSubmit}>
226
+ <div style={{ marginBottom: '15px' }}>
227
+ <label style={{ display: 'block', marginBottom: '5px', fontWeight: '500' }}>
228
+ Email
229
+ </label>
230
+ <input
231
+ type="email"
232
+ name="email"
233
+ value={formData.email}
234
+ onChange={handleInputChange}
235
+ required
236
+ style={{
237
+ width: '100%',
238
+ padding: '10px',
239
+ border: '1px solid #ddd',
240
+ borderRadius: '4px',
241
+ fontSize: '16px'
242
+ }}
243
+ />
244
+ </div>
245
+
246
+ <div style={{ marginBottom: '15px' }}>
247
+ <label style={{ display: 'block', marginBottom: '5px', fontWeight: '500' }}>
248
+ Card Number
249
+ </label>
250
+ <input
251
+ type="text"
252
+ name="cardNumber"
253
+ value={formData.cardNumber}
254
+ onChange={handleInputChange}
255
+ placeholder="1234 5678 9012 3456"
256
+ required
257
+ style={{
258
+ width: '100%',
259
+ padding: '10px',
260
+ border: '1px solid #ddd',
261
+ borderRadius: '4px',
262
+ fontSize: '16px'
263
+ }}
264
+ />
265
+ </div>
266
+
267
+ <div style={{ marginBottom: '15px' }}>
268
+ <label style={{ display: 'block', marginBottom: '5px', fontWeight: '500' }}>
269
+ Expiry Date
270
+ </label>
271
+ <input
272
+ type="text"
273
+ name="expiry"
274
+ value={formData.expiry}
275
+ onChange={handleInputChange}
276
+ placeholder="MM/YY"
277
+ required
278
+ style={{
279
+ width: '100%',
280
+ padding: '10px',
281
+ border: '1px solid #ddd',
282
+ borderRadius: '4px',
283
+ fontSize: '16px'
284
+ }}
285
+ />
286
+ </div>
287
+
288
+ <div style={{ marginBottom: '15px' }}>
289
+ <label style={{ display: 'block', marginBottom: '5px', fontWeight: '500' }}>
290
+ CVC
291
+ </label>
292
+ <input
293
+ type="text"
294
+ name="cvc"
295
+ value={formData.cvc}
296
+ onChange={handleInputChange}
297
+ placeholder="123"
298
+ required
299
+ style={{
300
+ width: '100%',
301
+ padding: '10px',
302
+ border: '1px solid #ddd',
303
+ borderRadius: '4px',
304
+ fontSize: '16px'
305
+ }}
306
+ />
307
+ </div>
308
+
309
+ <button
310
+ type="submit"
311
+ disabled={loading}
312
+ style={{
313
+ width: '100%',
314
+ padding: '12px',
315
+ background: loading ? '#ccc' : '#007bff',
316
+ color: 'white',
317
+ border: 'none',
318
+ borderRadius: '4px',
319
+ fontSize: '16px',
320
+ cursor: loading ? 'not-allowed' : 'pointer'
321
+ }}
322
+ >
323
+ {loading ? 'Processing...' : \`Pay ₱\${(amount / 100).toFixed(2)}\`}
324
+ </button>
325
+ </form>
326
+ </div>
327
+ </div>
328
+ );
329
+ };
330
+
331
+ export default CheckoutForm;`;
332
+ }
333
+ export function getVueTemplate() {
334
+ return `<template>
335
+ <div class="checkout-container">
336
+ <div class="checkout-form">
337
+ <h2>Complete Your Payment</h2>
338
+ <form @submit.prevent="handleSubmit">
339
+ <div class="form-group">
340
+ <label for="email">Email</label>
341
+ <input
342
+ v-model="formData.email"
343
+ type="email"
344
+ id="email"
345
+ required
346
+ >
347
+ </div>
348
+
349
+ <div class="form-group">
350
+ <label for="cardNumber">Card Number</label>
351
+ <input
352
+ v-model="formData.cardNumber"
353
+ type="text"
354
+ id="cardNumber"
355
+ placeholder="1234 5678 9012 3456"
356
+ required
357
+ >
358
+ </div>
359
+
360
+ <div class="form-group">
361
+ <label for="expiry">Expiry Date</label>
362
+ <input
363
+ v-model="formData.expiry"
364
+ type="text"
365
+ id="expiry"
366
+ placeholder="MM/YY"
367
+ required
368
+ >
369
+ </div>
370
+
371
+ <div class="form-group">
372
+ <label for="cvc">CVC</label>
373
+ <input
374
+ v-model="formData.cvc"
375
+ type="text"
376
+ id="cvc"
377
+ placeholder="123"
378
+ required
379
+ >
380
+ </div>
381
+
382
+ <button
383
+ type="submit"
384
+ :disabled="loading"
385
+ class="pay-button"
386
+ >
387
+ {{ loading ? 'Processing...' : \`Pay ₱\${(amount / 100).toFixed(2)}\` }}
388
+ </button>
389
+ </form>
390
+ </div>
391
+ </div>
392
+ </template>
393
+
394
+ <script>
395
+ export default {
396
+ name: 'CheckoutForm',
397
+ props: {
398
+ clientKey: {
399
+ type: String,
400
+ required: true
401
+ },
402
+ paymentIntentId: {
403
+ type: String,
404
+ required: true
405
+ },
406
+ amount: {
407
+ type: Number,
408
+ required: true
409
+ }
410
+ },
411
+ data() {
412
+ return {
413
+ loading: false,
414
+ formData: {
415
+ email: '',
416
+ cardNumber: '',
417
+ expiry: '',
418
+ cvc: ''
419
+ }
420
+ };
421
+ },
422
+ methods: {
423
+ async handleSubmit() {
424
+ this.loading = true;
425
+
426
+ try {
427
+ // Load PayMongo script if not loaded
428
+ if (!window.Paymongo) {
429
+ await this.loadPayMongoScript();
430
+ }
431
+
432
+ const paymongo = new window.Paymongo(this.clientKey);
433
+
434
+ // Create payment method
435
+ const paymentMethod = await paymongo.createPaymentMethod({
436
+ type: 'card',
437
+ details: {
438
+ card_number: this.formData.cardNumber.replace(/\\s/g, ''),
439
+ exp_month: parseInt(this.formData.expiry.split('/')[0]),
440
+ exp_year: 2000 + parseInt(this.formData.expiry.split('/')[1]),
441
+ cvc: this.formData.cvc,
442
+ },
443
+ billing: {
444
+ email: this.formData.email,
445
+ },
446
+ });
447
+
448
+ // Attach payment method to payment intent
449
+ const result = await paymongo.attachPaymentIntent(this.paymentIntentId, {
450
+ payment_method: paymentMethod.id,
451
+ return_url: window.location.origin + '/success',
452
+ });
453
+
454
+ this.$emit('success', result);
455
+
456
+ } catch (error) {
457
+ console.error('Payment failed:', error);
458
+ this.$emit('error', error);
459
+ } finally {
460
+ this.loading = false;
461
+ }
462
+ },
463
+
464
+ loadPayMongoScript() {
465
+ return new Promise((resolve, reject) => {
466
+ const script = document.createElement('script');
467
+ script.src = 'https://js.paymongo.com/v1/paymongo.js';
468
+ script.onload = resolve;
469
+ script.onerror = reject;
470
+ document.head.appendChild(script);
471
+ });
472
+ }
473
+ }
474
+ };
475
+ </script>
476
+
477
+ <style scoped>
478
+ .checkout-container {
479
+ max-width: 400px;
480
+ margin: 50px auto;
481
+ padding: 20px;
482
+ }
483
+
484
+ .checkout-form {
485
+ background: #f9f9f9;
486
+ padding: 20px;
487
+ border-radius: 8px;
488
+ }
489
+
490
+ .form-group {
491
+ margin-bottom: 15px;
492
+ }
493
+
494
+ label {
495
+ display: block;
496
+ margin-bottom: 5px;
497
+ font-weight: 500;
498
+ }
499
+
500
+ input {
501
+ width: 100%;
502
+ padding: 10px;
503
+ border: 1px solid #ddd;
504
+ border-radius: 4px;
505
+ font-size: 16px;
506
+ box-sizing: border-box;
507
+ }
508
+
509
+ .pay-button {
510
+ width: 100%;
511
+ padding: 12px;
512
+ background: #007bff;
513
+ color: white;
514
+ border: none;
515
+ border-radius: 4px;
516
+ font-size: 16px;
517
+ cursor: pointer;
518
+ }
519
+
520
+ .pay-button:hover:not(:disabled) {
521
+ background: #0056b3;
522
+ }
523
+
524
+ .pay-button:disabled {
525
+ background: #ccc;
526
+ cursor: not-allowed;
527
+ }
528
+ </style>`;
529
+ }
530
+ export function getCheckoutPageTemplate(language) {
531
+ switch (language) {
532
+ case 'react':
533
+ return { code: getReactTemplate(), extension: 'jsx' };
534
+ case 'vue':
535
+ return { code: getVueTemplate(), extension: 'vue' };
536
+ default:
537
+ return { code: getHtmlTemplate(), extension: 'html' };
538
+ }
539
+ }
@@ -0,0 +1,5 @@
1
+ export { getWebhookHandlerTemplate as getJavaScriptWebhookHandler } from './webhook-handler/javascript.js';
2
+ export { getWebhookHandlerTemplate as getTypeScriptWebhookHandler } from './webhook-handler/typescript.js';
3
+ export { getPaymentIntentTemplate as getJavaScriptPaymentIntent } from './payment-intent/javascript.js';
4
+ export { getPaymentIntentTemplate as getTypeScriptPaymentIntent } from './payment-intent/typescript.js';
5
+ export { getCheckoutPageTemplate, getHtmlTemplate, getReactTemplate, getVueTemplate } from './checkout-page/index.js';
@@ -0,0 +1,71 @@
1
+ export function getPaymentIntentTemplate(methods) {
2
+ return `const axios = require('axios');
3
+
4
+ // PayMongo API credentials
5
+ const PAYMONGO_SECRET_KEY = process.env.PAYMONGO_SECRET_KEY;
6
+ const PAYMONGO_PUBLIC_KEY = process.env.PAYMONGO_PUBLIC_KEY;
7
+
8
+ async function createPaymentIntent(amount, currency = 'PHP', description = '') {
9
+ try {
10
+ const response = await axios.post(
11
+ 'https://api.paymongo.com/v1/payment_intents',
12
+ {
13
+ data: {
14
+ attributes: {
15
+ amount: amount, // Amount in centavos (e.g., 10000 = ₱100.00)
16
+ currency: currency,
17
+ description: description,
18
+ payment_method_allowed: ${JSON.stringify(methods)},
19
+ }
20
+ }
21
+ },
22
+ {
23
+ headers: {
24
+ 'Authorization': \`Basic \${Buffer.from(PAYMONGO_SECRET_KEY + ':').toString('base64')}\`,
25
+ 'Content-Type': 'application/json',
26
+ }
27
+ }
28
+ );
29
+
30
+ const paymentIntent = response.data.data;
31
+
32
+ console.log('Payment Intent created:', paymentIntent.id);
33
+ console.log('Client Key:', paymentIntent.attributes.client_key);
34
+ console.log('Amount:', (paymentIntent.attributes.amount / 100).toFixed(2), paymentIntent.attributes.currency);
35
+
36
+ return {
37
+ id: paymentIntent.id,
38
+ clientKey: paymentIntent.attributes.client_key,
39
+ amount: paymentIntent.attributes.amount,
40
+ currency: paymentIntent.attributes.currency,
41
+ status: paymentIntent.attributes.status
42
+ };
43
+
44
+ } catch (error) {
45
+ console.error('Error creating payment intent:', error.response?.data || error.message);
46
+ throw error;
47
+ }
48
+ }
49
+
50
+ // Example usage
51
+ async function example() {
52
+ try {
53
+ const paymentIntent = await createPaymentIntent(
54
+ 10000, // ₱100.00
55
+ 'PHP',
56
+ 'Sample payment'
57
+ );
58
+
59
+ console.log('Use this client key in your frontend:', paymentIntent.clientKey);
60
+
61
+ } catch (error) {
62
+ console.error('Failed to create payment intent');
63
+ }
64
+ }
65
+
66
+ module.exports = { createPaymentIntent };
67
+
68
+ if (require.main === module) {
69
+ example();
70
+ }`;
71
+ }
@@ -0,0 +1,95 @@
1
+ export function getPaymentIntentTemplate(methods) {
2
+ return `import axios from 'axios';
3
+
4
+ interface PaymentIntent {
5
+ id: string;
6
+ clientKey: string;
7
+ amount: number;
8
+ currency: string;
9
+ status: string;
10
+ }
11
+
12
+ interface PayMongoPaymentIntentResponse {
13
+ data: {
14
+ id: string;
15
+ attributes: {
16
+ amount: number;
17
+ currency: string;
18
+ description: string;
19
+ status: string;
20
+ client_key: string;
21
+ payment_method_allowed: string[];
22
+ };
23
+ };
24
+ }
25
+
26
+ // PayMongo API credentials
27
+ const PAYMONGO_SECRET_KEY = process.env.PAYMONGO_SECRET_KEY!;
28
+ const PAYMONGO_PUBLIC_KEY = process.env.PAYMONGO_PUBLIC_KEY!;
29
+
30
+ export async function createPaymentIntent(
31
+ amount: number,
32
+ currency: string = 'PHP',
33
+ description: string = ''
34
+ ): Promise<PaymentIntent> {
35
+ try {
36
+ const response = await axios.post<PayMongoPaymentIntentResponse>(
37
+ 'https://api.paymongo.com/v1/payment_intents',
38
+ {
39
+ data: {
40
+ attributes: {
41
+ amount: amount, // Amount in centavos (e.g., 10000 = ₱100.00)
42
+ currency: currency,
43
+ description: description,
44
+ payment_method_allowed: ${JSON.stringify(methods)},
45
+ }
46
+ }
47
+ },
48
+ {
49
+ headers: {
50
+ 'Authorization': \`Basic \${Buffer.from(PAYMONGO_SECRET_KEY + ':').toString('base64')}\`,
51
+ 'Content-Type': 'application/json',
52
+ }
53
+ }
54
+ );
55
+
56
+ const paymentIntent = response.data.data;
57
+
58
+ console.log('Payment Intent created:', paymentIntent.id);
59
+ console.log('Client Key:', paymentIntent.attributes.client_key);
60
+ console.log('Amount:', (paymentIntent.attributes.amount / 100).toFixed(2), paymentIntent.attributes.currency);
61
+
62
+ return {
63
+ id: paymentIntent.id,
64
+ clientKey: paymentIntent.attributes.client_key,
65
+ amount: paymentIntent.attributes.amount,
66
+ currency: paymentIntent.attributes.currency,
67
+ status: paymentIntent.attributes.status
68
+ };
69
+
70
+ } catch (error: any) {
71
+ console.error('Error creating payment intent:', error.response?.data || error.message);
72
+ throw error;
73
+ }
74
+ }
75
+
76
+ // Example usage
77
+ async function example(): Promise<void> {
78
+ try {
79
+ const paymentIntent = await createPaymentIntent(
80
+ 10000, // ₱100.00
81
+ 'PHP',
82
+ 'Sample payment'
83
+ );
84
+
85
+ console.log('Use this client key in your frontend:', paymentIntent.clientKey);
86
+
87
+ } catch (error) {
88
+ console.error('Failed to create payment intent');
89
+ }
90
+ }
91
+
92
+ if (require.main === module) {
93
+ example();
94
+ }`;
95
+ }