paymongo-cli 1.4.4 → 1.4.7

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.
Files changed (155) hide show
  1. package/.github/copilot-instructions.md +95 -95
  2. package/CHANGELOG.md +85 -1
  3. package/LICENSE +20 -20
  4. package/dist/.tsbuildinfo +1 -1
  5. package/dist/commands/config.js +30 -15
  6. package/dist/commands/dev/logs.js +3 -3
  7. package/dist/commands/dev/status.js +2 -2
  8. package/dist/commands/dev/stop.js +3 -3
  9. package/dist/commands/dev.js +9 -8
  10. package/dist/commands/env.js +6 -6
  11. package/dist/commands/generate/templates/checkout-page/index.js +520 -520
  12. package/dist/commands/generate/templates/payment-intent/javascript.js +68 -68
  13. package/dist/commands/generate/templates/payment-intent/typescript.js +92 -92
  14. package/dist/commands/generate/templates/webhook-handler/javascript.js +192 -147
  15. package/dist/commands/generate/templates/webhook-handler/typescript.js +147 -117
  16. package/dist/commands/generate.js +43 -37
  17. package/dist/commands/init.js +25 -8
  18. package/dist/commands/login.js +56 -19
  19. package/dist/commands/payments.js +9 -8
  20. package/dist/commands/team/index.js +11 -9
  21. package/dist/commands/trigger.js +58 -18
  22. package/dist/commands/webhooks.js +8 -7
  23. package/dist/index.js +9 -2
  24. package/dist/services/analytics/service.js +24 -19
  25. package/dist/services/api/client.js +16 -16
  26. package/dist/services/config/manager.js +6 -8
  27. package/dist/services/dev/process-manager.js +30 -32
  28. package/dist/services/dev/server.js +45 -39
  29. package/dist/services/team/service.js +4 -1
  30. package/dist/types/schemas.js +38 -9
  31. package/dist/utils/bulk.js +36 -4
  32. package/dist/utils/constants.js +11 -1
  33. package/dist/utils/errors.js +6 -0
  34. package/dist/utils/validator.js +10 -9
  35. package/dist/utils/webhook-store.js +18 -15
  36. package/eslint.config.ts +70 -70
  37. package/package.json +2 -2
  38. package/coverage/base.css +0 -224
  39. package/coverage/block-navigation.js +0 -87
  40. package/coverage/favicon.png +0 -0
  41. package/coverage/index.html +0 -281
  42. package/coverage/lcov-report/base.css +0 -224
  43. package/coverage/lcov-report/block-navigation.js +0 -87
  44. package/coverage/lcov-report/favicon.png +0 -0
  45. package/coverage/lcov-report/index.html +0 -281
  46. package/coverage/lcov-report/prettify.css +0 -1
  47. package/coverage/lcov-report/prettify.js +0 -2
  48. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  49. package/coverage/lcov-report/sorter.js +0 -210
  50. package/coverage/lcov.info +0 -5053
  51. package/coverage/prettify.css +0 -1
  52. package/coverage/prettify.js +0 -2
  53. package/coverage/sort-arrow-sprite.png +0 -0
  54. package/coverage/sorter.js +0 -210
  55. package/dist/commands/config.d.ts +0 -21
  56. package/dist/commands/config.d.ts.map +0 -1
  57. package/dist/commands/config.js.map +0 -1
  58. package/dist/commands/dev.d.ts +0 -16
  59. package/dist/commands/dev.d.ts.map +0 -1
  60. package/dist/commands/dev.js.map +0 -1
  61. package/dist/commands/env.d.ts +0 -4
  62. package/dist/commands/env.d.ts.map +0 -1
  63. package/dist/commands/env.js.map +0 -1
  64. package/dist/commands/init.d.ts +0 -15
  65. package/dist/commands/init.d.ts.map +0 -1
  66. package/dist/commands/init.js.map +0 -1
  67. package/dist/commands/login.d.ts +0 -20
  68. package/dist/commands/login.d.ts.map +0 -1
  69. package/dist/commands/login.js.map +0 -1
  70. package/dist/commands/payments.d.ts +0 -41
  71. package/dist/commands/payments.d.ts.map +0 -1
  72. package/dist/commands/payments.js.map +0 -1
  73. package/dist/commands/team/index.d.ts +0 -4
  74. package/dist/commands/team/index.d.ts.map +0 -1
  75. package/dist/commands/team/index.js.map +0 -1
  76. package/dist/commands/trigger.d.ts +0 -4
  77. package/dist/commands/trigger.d.ts.map +0 -1
  78. package/dist/commands/trigger.js.map +0 -1
  79. package/dist/commands/webhooks.d.ts +0 -23
  80. package/dist/commands/webhooks.d.ts.map +0 -1
  81. package/dist/commands/webhooks.js.map +0 -1
  82. package/dist/index.d.ts +0 -3
  83. package/dist/index.d.ts.map +0 -1
  84. package/dist/index.js.map +0 -1
  85. package/dist/services/analytics/service.d.ts +0 -35
  86. package/dist/services/analytics/service.d.ts.map +0 -1
  87. package/dist/services/analytics/service.js.map +0 -1
  88. package/dist/services/api/client.d.ts +0 -26
  89. package/dist/services/api/client.d.ts.map +0 -1
  90. package/dist/services/api/client.js.map +0 -1
  91. package/dist/services/api/rate-limiter.d.ts +0 -64
  92. package/dist/services/api/rate-limiter.d.ts.map +0 -1
  93. package/dist/services/api/rate-limiter.js.map +0 -1
  94. package/dist/services/api/undici-client.d.ts +0 -39
  95. package/dist/services/api/undici-client.d.ts.map +0 -1
  96. package/dist/services/api/undici-client.js +0 -288
  97. package/dist/services/api/undici-client.js.map +0 -1
  98. package/dist/services/config/manager.d.ts +0 -16
  99. package/dist/services/config/manager.d.ts.map +0 -1
  100. package/dist/services/config/manager.js.map +0 -1
  101. package/dist/services/dev/process-manager.d.ts +0 -50
  102. package/dist/services/dev/process-manager.d.ts.map +0 -1
  103. package/dist/services/dev/process-manager.js.map +0 -1
  104. package/dist/services/github/auth.d.ts +0 -15
  105. package/dist/services/github/auth.d.ts.map +0 -1
  106. package/dist/services/github/auth.js +0 -79
  107. package/dist/services/github/auth.js.map +0 -1
  108. package/dist/services/github/client.d.ts +0 -95
  109. package/dist/services/github/client.d.ts.map +0 -1
  110. package/dist/services/github/client.js +0 -130
  111. package/dist/services/github/client.js.map +0 -1
  112. package/dist/services/github/sync.d.ts +0 -26
  113. package/dist/services/github/sync.d.ts.map +0 -1
  114. package/dist/services/github/sync.js +0 -203
  115. package/dist/services/github/sync.js.map +0 -1
  116. package/dist/services/payments/simulator.d.ts +0 -28
  117. package/dist/services/payments/simulator.d.ts.map +0 -1
  118. package/dist/services/payments/simulator.js.map +0 -1
  119. package/dist/services/team/service.d.ts +0 -44
  120. package/dist/services/team/service.d.ts.map +0 -1
  121. package/dist/services/team/service.js.map +0 -1
  122. package/dist/services/web/server.d.ts +0 -31
  123. package/dist/services/web/server.d.ts.map +0 -1
  124. package/dist/services/web/server.js +0 -206
  125. package/dist/services/web/server.js.map +0 -1
  126. package/dist/types/paymongo.d.ts +0 -204
  127. package/dist/types/paymongo.d.ts.map +0 -1
  128. package/dist/types/paymongo.js.map +0 -1
  129. package/dist/types/schemas.d.ts +0 -80
  130. package/dist/types/schemas.d.ts.map +0 -1
  131. package/dist/types/schemas.js.map +0 -1
  132. package/dist/utils/bulk.d.ts +0 -62
  133. package/dist/utils/bulk.d.ts.map +0 -1
  134. package/dist/utils/bulk.js.map +0 -1
  135. package/dist/utils/cache.d.ts +0 -22
  136. package/dist/utils/cache.d.ts.map +0 -1
  137. package/dist/utils/cache.js.map +0 -1
  138. package/dist/utils/constants.d.ts +0 -32
  139. package/dist/utils/constants.d.ts.map +0 -1
  140. package/dist/utils/constants.js.map +0 -1
  141. package/dist/utils/errors.d.ts +0 -34
  142. package/dist/utils/errors.d.ts.map +0 -1
  143. package/dist/utils/errors.js.map +0 -1
  144. package/dist/utils/logger.d.ts +0 -20
  145. package/dist/utils/logger.d.ts.map +0 -1
  146. package/dist/utils/logger.js.map +0 -1
  147. package/dist/utils/spinner.d.ts +0 -17
  148. package/dist/utils/spinner.d.ts.map +0 -1
  149. package/dist/utils/spinner.js.map +0 -1
  150. package/dist/utils/validator.d.ts +0 -10
  151. package/dist/utils/validator.d.ts.map +0 -1
  152. package/dist/utils/validator.js.map +0 -1
  153. package/dist/utils/webhook-store.d.ts +0 -22
  154. package/dist/utils/webhook-store.d.ts.map +0 -1
  155. package/dist/utils/webhook-store.js.map +0 -1
@@ -1,530 +1,530 @@
1
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>
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
134
  </html>`;
135
135
  }
136
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
-
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
331
  export default CheckoutForm;`;
332
332
  }
333
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
- }
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
528
  </style>`;
529
529
  }
530
530
  export function getCheckoutPageTemplate(language) {