@bloque/payments-react 0.0.6 → 0.0.8
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.
- package/README.md +13 -293
- package/dist/bloque-checkout.d.ts +39 -24
- package/dist/bloque-checkout.js +33 -23
- package/dist/index.d.ts +2 -4
- package/dist/index.js +2 -3
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,318 +1,38 @@
|
|
|
1
1
|
# @bloque/payments-react
|
|
2
2
|
|
|
3
|
-
React
|
|
3
|
+
React components for integrating Bloque hosted checkout into your React application.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
|
|
9
|
-
bun add @bloque/payments-react
|
|
10
|
-
|
|
11
|
-
# Using pnpm
|
|
12
|
-
pnpm add @bloque/payments-react
|
|
13
|
-
|
|
14
|
-
# Using npm
|
|
15
|
-
npm install @bloque/payments-react
|
|
16
|
-
|
|
17
|
-
# Using yarn
|
|
18
|
-
yarn add @bloque/payments-react
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
## Usage
|
|
22
|
-
|
|
23
|
-
### How it Works
|
|
24
|
-
|
|
25
|
-
```
|
|
26
|
-
┌─────────────────┐ ┌─────────────────┐ ┌──────────────┐
|
|
27
|
-
│ React Component │─────▶│ Your Backend │─────▶│ Bloque API │
|
|
28
|
-
│ (Frontend) │ │ (SDK Usage) │ │ │
|
|
29
|
-
└─────────────────┘ └─────────────────┘ └──────────────┘
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
1. **React Component** captures payment data from user
|
|
33
|
-
2. **`onSubmit`** sends complete `PaymentSubmitPayload` to your backend
|
|
34
|
-
3. **Your Backend** uses `@bloque/payments` to process the payment
|
|
35
|
-
|
|
36
|
-
### Basic Example
|
|
37
|
-
|
|
38
|
-
```tsx
|
|
39
|
-
import { BloqueCheckout } from '@bloque/payments-react';
|
|
40
|
-
import type { PaymentSubmitPayload } from '@bloque/payments-react';
|
|
41
|
-
|
|
42
|
-
function App() {
|
|
43
|
-
const handleSubmit = async (payload: PaymentSubmitPayload) => {
|
|
44
|
-
const response = await fetch('/api/payments', {
|
|
45
|
-
method: 'POST',
|
|
46
|
-
headers: { 'Content-Type': 'application/json' },
|
|
47
|
-
body: JSON.stringify(payload),
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
if (!response.ok) {
|
|
51
|
-
throw new Error('Payment failed');
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
return response.json();
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
return (
|
|
58
|
-
<BloqueCheckout
|
|
59
|
-
onSubmit={handleSubmit}
|
|
60
|
-
requireEmail={true}
|
|
61
|
-
/>
|
|
62
|
-
);
|
|
63
|
-
}
|
|
8
|
+
pnpm install @bloque/payments-react
|
|
64
9
|
```
|
|
65
10
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
```typescript
|
|
69
|
-
import { Bloque } from '@bloque/payments';
|
|
70
|
-
|
|
71
|
-
const bloque = new Bloque({
|
|
72
|
-
apiKey: process.env.BLOQUE_API_KEY!,
|
|
73
|
-
mode: 'production',
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
app.post('/api/payments', async (req, res) => {
|
|
77
|
-
const payload = req.body;
|
|
78
|
-
|
|
79
|
-
const payment = await bloque.payments.create({
|
|
80
|
-
payment: payload,
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
res.json(payment);
|
|
84
|
-
});
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
### With Configuration and Appearance
|
|
11
|
+
## Quick Start
|
|
88
12
|
|
|
89
13
|
```tsx
|
|
90
14
|
import { BloqueCheckout } from '@bloque/payments-react';
|
|
91
|
-
import type {
|
|
92
|
-
CheckoutConfig,
|
|
93
|
-
AppearanceConfig,
|
|
94
|
-
PaymentSubmitPayload,
|
|
95
|
-
} from '@bloque/payments-react';
|
|
96
15
|
|
|
97
16
|
function CheckoutPage() {
|
|
98
|
-
const config: CheckoutConfig = {
|
|
99
|
-
payment_methods: ['card', 'pse'],
|
|
100
|
-
amount: 120_000,
|
|
101
|
-
currency: 'COP',
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
const appearance: AppearanceConfig = {
|
|
105
|
-
primaryColor: '#10b981',
|
|
106
|
-
borderRadius: '12px',
|
|
107
|
-
fontFamily: 'Inter, system-ui, sans-serif',
|
|
108
|
-
};
|
|
109
|
-
|
|
110
|
-
const handleSubmit = async (payload: PaymentSubmitPayload) => {
|
|
111
|
-
const response = await fetch('/api/payments', {
|
|
112
|
-
method: 'POST',
|
|
113
|
-
headers: { 'Content-Type': 'application/json' },
|
|
114
|
-
body: JSON.stringify(payload),
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
if (!response.ok) {
|
|
118
|
-
throw new Error('Payment failed');
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
return response.json();
|
|
122
|
-
};
|
|
123
|
-
|
|
124
|
-
const handleSuccess = (event: CustomEvent<PaymentSubmitPayload>) => {
|
|
125
|
-
console.log('Payment successful!', event.detail);
|
|
126
|
-
window.location.href = '/success';
|
|
127
|
-
};
|
|
128
|
-
|
|
129
|
-
const handleError = (event: CustomEvent<PaymentSubmitPayload & { error: string }>) => {
|
|
130
|
-
console.error('Payment failed:', event.detail.error);
|
|
131
|
-
};
|
|
132
|
-
|
|
133
17
|
return (
|
|
134
18
|
<BloqueCheckout
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
onError={
|
|
19
|
+
checkoutId="checkout_123abc"
|
|
20
|
+
onSuccess={(data) => {
|
|
21
|
+
console.log('Payment successful!', data);
|
|
22
|
+
}}
|
|
23
|
+
onError={(error) => {
|
|
24
|
+
console.error('Payment failed:', error);
|
|
25
|
+
}}
|
|
140
26
|
/>
|
|
141
27
|
);
|
|
142
28
|
}
|
|
143
29
|
```
|
|
144
30
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
```tsx
|
|
148
|
-
import { BloqueCheckout } from '@bloque/payments-react';
|
|
149
|
-
|
|
150
|
-
function App() {
|
|
151
|
-
return (
|
|
152
|
-
<div className="checkout-container">
|
|
153
|
-
<BloqueCheckout
|
|
154
|
-
onSubmit={handleSubmit}
|
|
155
|
-
className="custom-checkout"
|
|
156
|
-
style={{ maxWidth: '600px', margin: '0 auto' }}
|
|
157
|
-
/>
|
|
158
|
-
</div>
|
|
159
|
-
);
|
|
160
|
-
}
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
## Props
|
|
164
|
-
|
|
165
|
-
### `BloqueCheckout`
|
|
166
|
-
|
|
167
|
-
| Prop | Type | Default | Description |
|
|
168
|
-
|------|------|---------|-------------|
|
|
169
|
-
| `config` | `CheckoutConfig` | `undefined` | Configuration object from backend SDK |
|
|
170
|
-
| `appearance` | `AppearanceConfig` | `undefined` | Appearance customization |
|
|
171
|
-
| `amount` | `number` | `undefined` | Payment amount (can also be set via `config.amount`) |
|
|
172
|
-
| `availableMethods` | `PaymentMethodType[]` | `['card', 'pse', 'cash']` | Available payment methods |
|
|
173
|
-
| `requireEmail` | `boolean` | `true` | Whether email is required for card payments |
|
|
174
|
-
| `showMethodSelector` | `boolean` | `true` | Whether to show the payment method selector |
|
|
175
|
-
| `onSubmit` | `function` | `undefined` | Function called when user submits payment |
|
|
176
|
-
| `onSuccess` | `function` | `undefined` | Event handler for successful payment |
|
|
177
|
-
| `onError` | `function` | `undefined` | Event handler for payment errors |
|
|
178
|
-
| `className` | `string` | `undefined` | CSS class name |
|
|
179
|
-
| `style` | `React.CSSProperties` | `undefined` | Inline styles |
|
|
180
|
-
|
|
181
|
-
### `CheckoutConfig`
|
|
182
|
-
|
|
183
|
-
```typescript
|
|
184
|
-
interface CheckoutConfig {
|
|
185
|
-
payment_methods?: PaymentMethodType[];
|
|
186
|
-
amount?: number;
|
|
187
|
-
currency?: string;
|
|
188
|
-
}
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
### `AppearanceConfig`
|
|
192
|
-
|
|
193
|
-
```typescript
|
|
194
|
-
interface AppearanceConfig {
|
|
195
|
-
primaryColor?: string;
|
|
196
|
-
borderRadius?: string;
|
|
197
|
-
fontFamily?: string;
|
|
198
|
-
}
|
|
199
|
-
```
|
|
200
|
-
|
|
201
|
-
## TypeScript
|
|
202
|
-
|
|
203
|
-
The package includes full TypeScript definitions with discriminated union types for type safety:
|
|
204
|
-
|
|
205
|
-
```typescript
|
|
206
|
-
import type {
|
|
207
|
-
BloqueCheckoutProps,
|
|
208
|
-
PaymentSubmitPayload,
|
|
209
|
-
CheckoutConfig,
|
|
210
|
-
AppearanceConfig,
|
|
211
|
-
} from '@bloque/payments-react';
|
|
212
|
-
|
|
213
|
-
// PaymentSubmitPayload is a discriminated union type
|
|
214
|
-
// TypeScript automatically narrows the type based on the 'type' field
|
|
215
|
-
const handleSubmit = async (payload: PaymentSubmitPayload) => {
|
|
216
|
-
// Type narrowing example
|
|
217
|
-
switch (payload.type) {
|
|
218
|
-
case 'card':
|
|
219
|
-
// payload.data is CardPaymentFormData
|
|
220
|
-
console.log('Card ending in:', payload.data.cardNumber.slice(-4));
|
|
221
|
-
break;
|
|
222
|
-
case 'pse':
|
|
223
|
-
// payload.data is PSEPaymentFormData
|
|
224
|
-
console.log('Bank:', payload.data.bankCode);
|
|
225
|
-
break;
|
|
226
|
-
case 'cash':
|
|
227
|
-
// payload.data is CashPaymentFormData
|
|
228
|
-
console.log('Name:', payload.data.fullName);
|
|
229
|
-
break;
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
// Send complete payload to your backend
|
|
233
|
-
const response = await fetch('/api/payments', {
|
|
234
|
-
method: 'POST',
|
|
235
|
-
headers: { 'Content-Type': 'application/json' },
|
|
236
|
-
body: JSON.stringify(payload),
|
|
237
|
-
});
|
|
238
|
-
|
|
239
|
-
return response.json();
|
|
240
|
-
};
|
|
241
|
-
```
|
|
242
|
-
|
|
243
|
-
## Events
|
|
244
|
-
|
|
245
|
-
### `onSubmit`
|
|
246
|
-
|
|
247
|
-
Called when the user submits a payment form. Send the complete payload to your backend, which will use `@bloque/payments` to process the payment.
|
|
248
|
-
|
|
249
|
-
```typescript
|
|
250
|
-
onSubmit?: (payload: PaymentSubmitPayload) => Promise<void>;
|
|
251
|
-
```
|
|
252
|
-
|
|
253
|
-
**Example:**
|
|
254
|
-
```typescript
|
|
255
|
-
const handleSubmit = async (payload: PaymentSubmitPayload) => {
|
|
256
|
-
const response = await fetch('/api/payments', {
|
|
257
|
-
method: 'POST',
|
|
258
|
-
headers: { 'Content-Type': 'application/json' },
|
|
259
|
-
body: JSON.stringify(payload),
|
|
260
|
-
});
|
|
261
|
-
|
|
262
|
-
if (!response.ok) throw new Error('Payment failed');
|
|
263
|
-
return response.json();
|
|
264
|
-
};
|
|
265
|
-
```
|
|
266
|
-
|
|
267
|
-
**Type definition:**
|
|
268
|
-
```typescript
|
|
269
|
-
type PaymentSubmitPayload =
|
|
270
|
-
| { type: 'card'; data: CardPaymentFormData }
|
|
271
|
-
| { type: 'pse'; data: PSEPaymentFormData }
|
|
272
|
-
| { type: 'cash'; data: CashPaymentFormData };
|
|
273
|
-
```
|
|
274
|
-
|
|
275
|
-
**Your backend should:**
|
|
276
|
-
```typescript
|
|
277
|
-
import { Bloque } from '@bloque/payments';
|
|
278
|
-
|
|
279
|
-
const bloque = new Bloque({
|
|
280
|
-
apiKey: process.env.BLOQUE_API_KEY!,
|
|
281
|
-
mode: 'production',
|
|
282
|
-
});
|
|
283
|
-
|
|
284
|
-
app.post('/api/payments', async (req, res) => {
|
|
285
|
-
const payload = req.body;
|
|
286
|
-
|
|
287
|
-
const payment = await bloque.payments.create({
|
|
288
|
-
payment: payload,
|
|
289
|
-
});
|
|
290
|
-
|
|
291
|
-
res.json(payment);
|
|
292
|
-
});
|
|
293
|
-
```
|
|
294
|
-
|
|
295
|
-
### `onSuccess`
|
|
296
|
-
|
|
297
|
-
Fired when the payment is successfully processed.
|
|
298
|
-
|
|
299
|
-
```typescript
|
|
300
|
-
onSuccess?: (event: CustomEvent<PaymentSubmitPayload>) => void;
|
|
301
|
-
```
|
|
302
|
-
|
|
303
|
-
### `onError`
|
|
304
|
-
|
|
305
|
-
Fired when payment processing fails.
|
|
306
|
-
|
|
307
|
-
```typescript
|
|
308
|
-
onError?: (event: CustomEvent<PaymentSubmitPayload & { error: string }>) => void;
|
|
309
|
-
```
|
|
31
|
+
## Documentation
|
|
310
32
|
|
|
311
|
-
|
|
33
|
+
For complete documentation, examples, and API reference, visit:
|
|
312
34
|
|
|
313
|
-
|
|
314
|
-
- **PSE** - Colombian online banking system
|
|
315
|
-
- **Cash** - Generate receipt for cash payment at physical locations
|
|
35
|
+
**[https://docs.bloque.app/pay](https://docs.bloque.app/pay)**
|
|
316
36
|
|
|
317
37
|
## License
|
|
318
38
|
|
|
@@ -1,27 +1,42 @@
|
|
|
1
|
-
import '@bloque/payments-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
export interface BloqueCheckoutProps {
|
|
11
|
-
config?: CheckoutConfig;
|
|
12
|
-
appearance?: AppearanceConfig;
|
|
13
|
-
amount?: number;
|
|
14
|
-
availableMethods?: PaymentMethodType[];
|
|
15
|
-
requireEmail?: boolean;
|
|
16
|
-
showMethodSelector?: boolean;
|
|
17
|
-
onSubmit?: (payload: PaymentSubmitPayload) => Promise<PaymentResponse | undefined>;
|
|
18
|
-
onSuccess?: (response: PaymentResponse) => void;
|
|
19
|
-
onError?: (error: {
|
|
20
|
-
message: string;
|
|
21
|
-
data: unknown;
|
|
22
|
-
type: string;
|
|
23
|
-
}) => void;
|
|
1
|
+
import { type BloqueCheckoutOptions } from '@bloque/payments-core';
|
|
2
|
+
export interface BloqueCheckoutProps extends Omit<BloqueCheckoutOptions, 'checkoutId'> {
|
|
3
|
+
/**
|
|
4
|
+
* The checkout ID returned from your backend after creating a checkout session
|
|
5
|
+
*/
|
|
6
|
+
checkoutId: string;
|
|
7
|
+
/**
|
|
8
|
+
* Additional CSS class name for the container div
|
|
9
|
+
*/
|
|
24
10
|
className?: string;
|
|
11
|
+
/**
|
|
12
|
+
* Additional inline styles for the container div
|
|
13
|
+
*/
|
|
25
14
|
style?: React.CSSProperties;
|
|
26
15
|
}
|
|
27
|
-
|
|
16
|
+
/**
|
|
17
|
+
* BloqueCheckout React component
|
|
18
|
+
*
|
|
19
|
+
* This component renders an iframe with the Bloque hosted checkout page.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```tsx
|
|
23
|
+
* import { BloqueCheckout } from '@bloque/payments-react';
|
|
24
|
+
*
|
|
25
|
+
* function MyCheckout() {
|
|
26
|
+
* return (
|
|
27
|
+
* <BloqueCheckout
|
|
28
|
+
* checkoutId="checkout_123abc"
|
|
29
|
+
* onSuccess={(data) => {
|
|
30
|
+
* console.log('Payment successful!', data);
|
|
31
|
+
* }}
|
|
32
|
+
* onError={(error) => {
|
|
33
|
+
* console.error('Payment failed:', error);
|
|
34
|
+
* }}
|
|
35
|
+
* />
|
|
36
|
+
* );
|
|
37
|
+
* }
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export declare function BloqueCheckout({ checkoutId, publicApiKey, mode, checkoutUrl, appearance, onReady, onSuccess, onError, onPending, iframeStyles, className, style, }: BloqueCheckoutProps): import("react/jsx-runtime").JSX.Element;
|
|
41
|
+
export type { AppearanceConfig, BloqueCheckoutOptions, BloqueInitOptions, PaymentResult, } from '@bloque/payments-core';
|
|
42
|
+
export { BloqueCheckout as BloqueCheckoutCore, init, } from '@bloque/payments-core';
|
package/dist/bloque-checkout.js
CHANGED
|
@@ -1,35 +1,45 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
|
-
import "@bloque/payments-
|
|
2
|
+
import { BloqueCheckout, init } from "@bloque/payments-core";
|
|
3
3
|
import { useEffect, useRef } from "react";
|
|
4
|
-
function
|
|
4
|
+
function bloque_checkout_BloqueCheckout({ checkoutId, publicApiKey, mode, checkoutUrl, appearance, onReady, onSuccess, onError, onPending, iframeStyles, className, style }) {
|
|
5
|
+
const containerRef = useRef(null);
|
|
5
6
|
const checkoutRef = useRef(null);
|
|
6
7
|
useEffect(()=>{
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
8
|
+
if (!containerRef.current) return;
|
|
9
|
+
const checkout = new BloqueCheckout({
|
|
10
|
+
checkoutId,
|
|
11
|
+
publicApiKey,
|
|
12
|
+
mode,
|
|
13
|
+
checkoutUrl,
|
|
14
|
+
appearance,
|
|
15
|
+
onReady,
|
|
16
|
+
onSuccess,
|
|
17
|
+
onError,
|
|
18
|
+
onPending,
|
|
19
|
+
iframeStyles
|
|
20
|
+
});
|
|
21
|
+
const iframe = checkout.createIframe();
|
|
22
|
+
containerRef.current.appendChild(iframe);
|
|
23
|
+
checkoutRef.current = checkout;
|
|
24
|
+
return ()=>{
|
|
25
|
+
checkout.destroy();
|
|
26
|
+
};
|
|
18
27
|
}, [
|
|
19
|
-
|
|
28
|
+
checkoutId,
|
|
29
|
+
publicApiKey,
|
|
30
|
+
mode,
|
|
31
|
+
checkoutUrl,
|
|
20
32
|
appearance,
|
|
21
|
-
|
|
22
|
-
availableMethods,
|
|
23
|
-
requireEmail,
|
|
24
|
-
showMethodSelector,
|
|
25
|
-
onSubmit,
|
|
33
|
+
onReady,
|
|
26
34
|
onSuccess,
|
|
27
|
-
onError
|
|
35
|
+
onError,
|
|
36
|
+
onPending,
|
|
37
|
+
iframeStyles
|
|
28
38
|
]);
|
|
29
|
-
return /*#__PURE__*/ jsx("
|
|
30
|
-
ref:
|
|
39
|
+
return /*#__PURE__*/ jsx("div", {
|
|
40
|
+
ref: containerRef,
|
|
31
41
|
className: className,
|
|
32
42
|
style: style
|
|
33
43
|
});
|
|
34
44
|
}
|
|
35
|
-
export { BloqueCheckout };
|
|
45
|
+
export { bloque_checkout_BloqueCheckout as BloqueCheckout, BloqueCheckout as BloqueCheckoutCore, init };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,2 @@
|
|
|
1
|
-
export type { AppearanceConfig,
|
|
2
|
-
export { init } from '
|
|
3
|
-
export type { BloqueCheckoutProps } from './bloque-checkout';
|
|
4
|
-
export { BloqueCheckout } from './bloque-checkout';
|
|
1
|
+
export type { AppearanceConfig, BloqueCheckoutOptions, BloqueCheckoutProps, BloqueInitOptions, PaymentResult, } from './bloque-checkout';
|
|
2
|
+
export { BloqueCheckout, BloqueCheckoutCore, init, } from './bloque-checkout';
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
import { init } from "
|
|
2
|
-
|
|
3
|
-
export { BloqueCheckout, init };
|
|
1
|
+
import { BloqueCheckout, BloqueCheckoutCore, init } from "./bloque-checkout.js";
|
|
2
|
+
export { BloqueCheckout, BloqueCheckoutCore, init };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bloque/payments-react",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.8",
|
|
4
4
|
"description": "React wrapper for Bloque payments web components",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"provenance": true
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@bloque/payments-
|
|
37
|
+
"@bloque/payments-core": "0.0.8"
|
|
38
38
|
},
|
|
39
39
|
"peerDependencies": {
|
|
40
40
|
"react": ">=16.9.0",
|