@gmisoftware/react-native-pay 0.0.10 → 0.0.11

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 (2) hide show
  1. package/README.md +1130 -0
  2. package/package.json +3 -1
package/README.md ADDED
@@ -0,0 +1,1130 @@
1
+ # React Native Pay
2
+
3
+ <div align="center">
4
+
5
+ A unified React Native payment module supporting **Apple Pay** (iOS) and **Google Pay** (Android) with a consistent, type-safe API.
6
+
7
+ [![npm version](https://img.shields.io/npm/v/@gmisoftware/react-native-pay.svg)](https://www.npmjs.com/package/@gmisoftware/react-native-pay)
8
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
9
+ [![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue.svg)](https://www.typescriptlang.org/)
10
+ [![Expo Compatible](https://img.shields.io/badge/Expo-Compatible-000020.svg)](https://expo.dev/)
11
+
12
+ Built with [Nitro Modules](https://nitro.margelo.com/) for high-performance native integration.
13
+
14
+ [Features](#features) • [Installation](#installation) • [Quick Start](#quick-start) • [Documentation](#documentation) • [API Reference](#api-reference)
15
+
16
+ </div>
17
+
18
+ ---
19
+
20
+ ## Features
21
+
22
+ - ✅ **Unified API** - Single interface for both Apple Pay and Google Pay
23
+ - ✅ **One Hook Does Everything** - Complete payment flow with `usePaymentCheckout()` hook
24
+ - ✅ **Native UI Components** - Platform-specific payment buttons with full customization
25
+ - ✅ **Type-Safe** - Comprehensive TypeScript definitions with full IntelliSense support
26
+ - ✅ **Configurable** - Dynamic environment and gateway configuration for both platforms
27
+ - ✅ **Built-in Cart** - Shopping cart functionality with batch operations
28
+ - ✅ **Modern Architecture** - Built with Nitro Modules for optimal performance
29
+ - ✅ **Expo Compatible** - Config plugins for seamless Expo integration
30
+ - ✅ **Production Ready** - Used in production apps with millions of transactions
31
+
32
+ ---
33
+
34
+ ## Installation
35
+
36
+ ### Step 1: Install React Native Nitro Modules
37
+
38
+ This package requires `react-native-nitro-modules` to work. Install it first:
39
+
40
+ ```bash
41
+ npm install react-native-nitro-modules
42
+ # or
43
+ yarn add react-native-nitro-modules
44
+ # or
45
+ bun add react-native-nitro-modules
46
+ ```
47
+
48
+ ### Step 2: Install React Native Pay
49
+
50
+ ```bash
51
+ npm install @gmisoftware/react-native-pay
52
+ # or
53
+ yarn add @gmisoftware/react-native-pay
54
+ # or
55
+ bun add @gmisoftware/react-native-pay
56
+ ```
57
+
58
+ ### Prerequisites
59
+
60
+ - React Native 0.70+
61
+ - React Native Nitro Modules 0.31.4+ (required)
62
+ - Expo 53+ (if using Expo)
63
+
64
+ ---
65
+
66
+ ## Platform Setup
67
+
68
+ ### iOS Setup (Apple Pay)
69
+
70
+ #### 1. Configure Expo Config Plugin
71
+
72
+ Add the Apple Pay plugin to your `app.json` or `app.config.js`:
73
+
74
+ ```js
75
+ {
76
+ "expo": {
77
+ "plugins": [
78
+ [
79
+ "@gmisoftware/react-native-pay",
80
+ {
81
+ "merchantIdentifier": "merchant.com.yourcompany.app"
82
+ }
83
+ ]
84
+ ]
85
+ }
86
+ }
87
+ ```
88
+
89
+ #### 2. Apple Developer Account Setup
90
+
91
+ 1. **Create a Merchant ID** in Apple Developer Portal:
92
+ - Go to [Certificates, Identifiers & Profiles](https://developer.apple.com/account/resources/identifiers/list/merchant)
93
+ - Create a new Merchant ID (e.g., `merchant.com.yourcompany.app`)
94
+ - Add it to your app's capabilities
95
+
96
+ 2. **Enable Apple Pay** in your App ID:
97
+ - Go to your App ID settings
98
+ - Enable "Apple Pay Payment Processing"
99
+ - Associate your Merchant ID
100
+
101
+ 3. **Create Payment Processing Certificate**:
102
+ - Create a Payment Processing Certificate for your Merchant ID
103
+ - Download and install it in your payment processor (Stripe, etc.)
104
+
105
+ #### 3. Run Prebuild (Expo)
106
+
107
+ ```bash
108
+ npx expo prebuild --clean
109
+ ```
110
+
111
+ ### Android Setup (Google Pay)
112
+
113
+ #### 1. Configure Expo Config Plugin
114
+
115
+ Add the Google Pay plugin to your `app.json` or `app.config.js`:
116
+
117
+ ```js
118
+ {
119
+ "expo": {
120
+ "plugins": [
121
+ [
122
+ "@gmisoftware/react-native-pay",
123
+ {
124
+ "enableGooglePay": true
125
+ }
126
+ ]
127
+ ]
128
+ }
129
+ }
130
+ ```
131
+
132
+ #### 2. Google Cloud Console Setup
133
+
134
+ 1. **Enable Google Pay API**:
135
+ - Go to [Google Cloud Console](https://console.cloud.google.com/)
136
+ - Enable the Google Pay API for your project
137
+
138
+ 2. **Register Your App** (Production Only):
139
+ - Submit your app for Google Pay approval
140
+ - Provide screenshots and business information
141
+ - Get your production gateway merchant ID from your payment processor
142
+
143
+ #### 3. Run Prebuild (Expo)
144
+
145
+ ```bash
146
+ npx expo prebuild --clean
147
+ ```
148
+
149
+ ### Combined Setup (Both Platforms)
150
+
151
+ For apps supporting both platforms:
152
+
153
+ ```js
154
+ {
155
+ "expo": {
156
+ "plugins": [
157
+ [
158
+ "@gmisoftware/react-native-pay",
159
+ {
160
+ "merchantIdentifier": "merchant.com.yourcompany.app",
161
+ "enableGooglePay": true
162
+ }
163
+ ]
164
+ ]
165
+ }
166
+ }
167
+ ```
168
+
169
+ ---
170
+
171
+ ## Quick Start
172
+
173
+ ### Basic Example with Hook (Recommended)
174
+
175
+ The easiest way to integrate payments - one hook handles everything:
176
+
177
+ ```typescript
178
+ import React from 'react'
179
+ import {
180
+ usePaymentCheckout,
181
+ ApplePayButton,
182
+ GooglePayButton,
183
+ } from '@gmisoftware/react-native-pay'
184
+ import { Platform, View, Text, Button, ActivityIndicator } from 'react-native'
185
+
186
+ function CheckoutScreen() {
187
+ const {
188
+ // Payment availability
189
+ canMakePayments,
190
+
191
+ // Cart management
192
+ items,
193
+ total,
194
+ addItem,
195
+ addItems,
196
+ removeItem,
197
+
198
+ // Payment processing
199
+ startPayment,
200
+ isProcessing,
201
+ error,
202
+ } = usePaymentCheckout({
203
+ merchantIdentifier: 'merchant.com.yourcompany.app',
204
+ currencyCode: 'USD',
205
+ countryCode: 'US',
206
+ })
207
+
208
+ const handleAddCoffee = () => {
209
+ addItem('Coffee', 4.99)
210
+ }
211
+
212
+ const handleAddFullOrder = () => {
213
+ addItems([
214
+ { label: 'Coffee', amount: 4.99 },
215
+ { label: 'Sandwich', amount: 8.99 },
216
+ { label: 'Tax', amount: 1.20, type: 'final' }
217
+ ])
218
+ }
219
+
220
+ const handlePay = async () => {
221
+ const result = await startPayment()
222
+
223
+ if (result?.success && result.token) {
224
+ // Send result.token to your server for processing
225
+ console.log('Payment successful:', result.transactionId)
226
+ console.log('Token:', result.token)
227
+
228
+ // Call your backend
229
+ await fetch('https://api.yourserver.com/process-payment', {
230
+ method: 'POST',
231
+ headers: { 'Content-Type': 'application/json' },
232
+ body: JSON.stringify({
233
+ token: result.token,
234
+ transactionId: result.transactionId,
235
+ }),
236
+ })
237
+ }
238
+ }
239
+
240
+ if (!canMakePayments) {
241
+ return (
242
+ <View>
243
+ <Text>Apple Pay or Google Pay is not available on this device</Text>
244
+ </View>
245
+ )
246
+ }
247
+
248
+ return (
249
+ <View style={{ padding: 20 }}>
250
+ <Button title="Add Coffee ($4.99)" onPress={handleAddCoffee} />
251
+ <Button title="Add Full Order" onPress={handleAddFullOrder} />
252
+
253
+ {items.map((item, index) => (
254
+ <View key={index} style={{ flexDirection: 'row', padding: 10 }}>
255
+ <Text>{item.label}: ${item.amount.toFixed(2)}</Text>
256
+ <Button title="Remove" onPress={() => removeItem(index)} />
257
+ </View>
258
+ ))}
259
+
260
+ <Text style={{ fontSize: 20, marginVertical: 10 }}>
261
+ Total: ${total.toFixed(2)}
262
+ </Text>
263
+
264
+ {error && (
265
+ <Text style={{ color: 'red', marginVertical: 10 }}>
266
+ Error: {error.message}
267
+ </Text>
268
+ )}
269
+
270
+ {isProcessing ? (
271
+ <ActivityIndicator size="large" />
272
+ ) : (
273
+ Platform.OS === 'ios' ? (
274
+ <ApplePayButton
275
+ buttonType="buy"
276
+ buttonStyle="black"
277
+ onPress={handlePay}
278
+ style={{ width: '100%', height: 48 }}
279
+ />
280
+ ) : (
281
+ <GooglePayButton
282
+ buttonType="buy"
283
+ theme="dark"
284
+ radius={4}
285
+ onPress={handlePay}
286
+ style={{ width: '100%', height: 48 }}
287
+ />
288
+ )
289
+ )}
290
+ </View>
291
+ )
292
+ }
293
+
294
+ export default CheckoutScreen
295
+ ```
296
+
297
+ ---
298
+
299
+ ## Documentation
300
+
301
+ ### Payment Flow Overview
302
+
303
+ ```
304
+ 1. Check availability → usePaymentCheckout() or HybridPaymentHandler.payServiceStatus()
305
+ 2. Build cart → addItem() / addItems()
306
+ 3. Display payment button → ApplePayButton / GooglePayButton
307
+ 4. Process payment → startPayment()
308
+ 5. Handle result → Send token to server
309
+ 6. Complete transaction → Server processes with payment gateway
310
+ ```
311
+
312
+ ### Google Pay Configuration
313
+
314
+ For Google Pay, you need to configure your payment gateway:
315
+
316
+ ```typescript
317
+ const checkout = usePaymentCheckout({
318
+ merchantIdentifier: 'merchant.com.yourcompany.app',
319
+ currencyCode: 'USD',
320
+ countryCode: 'US',
321
+ // Google Pay specific
322
+ googlePayEnvironment: 'TEST', // or 'PRODUCTION'
323
+ googlePayGateway: 'stripe',
324
+ googlePayGatewayMerchantId: 'your_stripe_merchant_id',
325
+ })
326
+ ```
327
+
328
+ #### Supported Payment Gateways
329
+
330
+ - **Stripe** - `googlePayGateway: 'stripe'`
331
+ - **Braintree** - `googlePayGateway: 'braintree'`
332
+ - **Square** - `googlePayGateway: 'square'`
333
+ - **Adyen** - `googlePayGateway: 'adyen'`
334
+ - **Authorize.net** - `googlePayGateway: 'authorizenet'`
335
+ - **Checkout.com** - `googlePayGateway: 'checkoutltd'`
336
+
337
+ For the complete list, see [Google Pay Gateway Tokens](https://developers.google.com/pay/api/android/reference/request-objects#gateway).
338
+
339
+ ---
340
+
341
+ ## API Reference
342
+
343
+ ### `usePaymentCheckout(config)`
344
+
345
+ The all-in-one hook for handling payments. Manages availability checking, cart state, and payment processing.
346
+
347
+ #### Configuration
348
+
349
+ ```typescript
350
+ interface UsePaymentCheckoutConfig {
351
+ merchantIdentifier: string
352
+ merchantName?: string
353
+ countryCode?: string // Default: 'US'
354
+ currencyCode?: string // Default: 'USD'
355
+ supportedNetworks?: string[] // Default: ['visa', 'mastercard', 'amex', 'discover']
356
+ merchantCapabilities?: string[] // Default: ['3DS']
357
+ // Google Pay specific (Android)
358
+ googlePayEnvironment?: 'TEST' | 'PRODUCTION'
359
+ googlePayGateway?: string
360
+ googlePayGatewayMerchantId?: string
361
+ }
362
+ ```
363
+
364
+ #### Returns
365
+
366
+ ```typescript
367
+ interface UsePaymentCheckoutReturn {
368
+ // Payment availability
369
+ canMakePayments: boolean // Can user make payments?
370
+ canSetupCards: boolean // Can user add cards?
371
+ isCheckingStatus: boolean // Loading state for availability check
372
+
373
+ // Cart management
374
+ items: PaymentItem[] // Current cart items
375
+ total: number // Total amount
376
+ addItem: (label: string, amount: number, type?: 'final' | 'pending') => void
377
+ addItems: (items: Array<{ label; amount; type? }>) => void
378
+ removeItem: (index: number) => void
379
+ updateItem: (index: number, updates: Partial<PaymentItem>) => void
380
+ clearItems: () => void
381
+
382
+ // Payment processing
383
+ startPayment: () => Promise<PaymentResult | null>
384
+ isProcessing: boolean // Payment in progress?
385
+ result: PaymentResult | null // Last payment result
386
+ error: Error | null // Last error
387
+
388
+ // Utilities
389
+ reset: () => void // Reset payment state
390
+ paymentRequest: PaymentRequest // Full request object
391
+ }
392
+ ```
393
+
394
+ #### Example
395
+
396
+ ```typescript
397
+ const checkout = usePaymentCheckout({
398
+ merchantIdentifier: 'merchant.com.example',
399
+ currencyCode: 'USD',
400
+ countryCode: 'US',
401
+ googlePayEnvironment: 'TEST',
402
+ googlePayGateway: 'stripe',
403
+ googlePayGatewayMerchantId: 'your_stripe_merchant_id',
404
+ })
405
+
406
+ // Add single item
407
+ checkout.addItem('Product', 29.99)
408
+
409
+ // Add multiple items at once
410
+ checkout.addItems([
411
+ { label: 'Product', amount: 29.99 },
412
+ { label: 'Shipping', amount: 5.0 },
413
+ { label: 'Tax', amount: 2.8, type: 'final' },
414
+ ])
415
+
416
+ // Process payment
417
+ const result = await checkout.startPayment()
418
+ ```
419
+
420
+ ---
421
+
422
+ ### `HybridPaymentHandler`
423
+
424
+ Low-level payment handler for direct control.
425
+
426
+ #### Methods
427
+
428
+ ##### `payServiceStatus(): PayServiceStatus`
429
+
430
+ Check payment service availability.
431
+
432
+ ```typescript
433
+ const status = HybridPaymentHandler.payServiceStatus()
434
+ console.log('Can make payments:', status.canMakePayments)
435
+ console.log('Can setup cards:', status.canSetupCards)
436
+ ```
437
+
438
+ **Returns:**
439
+
440
+ ```typescript
441
+ interface PayServiceStatus {
442
+ canMakePayments: boolean
443
+ canSetupCards: boolean
444
+ }
445
+ ```
446
+
447
+ ##### `startPayment(request: PaymentRequest): Promise<PaymentResult>`
448
+
449
+ Start a payment request.
450
+
451
+ ```typescript
452
+ const result = await HybridPaymentHandler.startPayment({
453
+ merchantIdentifier: 'merchant.com.example',
454
+ countryCode: 'US',
455
+ currencyCode: 'USD',
456
+ merchantCapabilities: ['3DS'],
457
+ supportedNetworks: ['visa', 'mastercard', 'amex'],
458
+ paymentItems: [{ label: 'Total', amount: 29.99, type: 'final' }],
459
+ })
460
+ ```
461
+
462
+ **Returns:**
463
+
464
+ ```typescript
465
+ interface PaymentResult {
466
+ success: boolean
467
+ transactionId?: string
468
+ token?: PaymentToken
469
+ error?: string
470
+ }
471
+
472
+ interface PaymentToken {
473
+ paymentMethod: PaymentMethod
474
+ transactionIdentifier: string
475
+ paymentData: string // Base64 encoded
476
+ }
477
+ ```
478
+
479
+ ##### `canMakePayments(usingNetworks: string[]): boolean`
480
+
481
+ Check if specific card networks are supported.
482
+
483
+ ```typescript
484
+ const canPay = HybridPaymentHandler.canMakePayments(['visa', 'mastercard'])
485
+ ```
486
+
487
+ ---
488
+
489
+ ### Button Components
490
+
491
+ #### `ApplePayButton` (iOS)
492
+
493
+ Native Apple Pay button with full customization.
494
+
495
+ ##### Props
496
+
497
+ ```typescript
498
+ interface ApplePayButtonProps {
499
+ buttonType?:
500
+ | 'plain'
501
+ | 'buy'
502
+ | 'setUp'
503
+ | 'inStore'
504
+ | 'donate'
505
+ | 'checkout'
506
+ | 'book'
507
+ | 'subscribe'
508
+ | 'reload'
509
+ | 'addMoney'
510
+ | 'topUp'
511
+ | 'order'
512
+ | 'rent'
513
+ | 'support'
514
+ | 'contribute'
515
+ | 'tip'
516
+
517
+ buttonStyle?: 'white' | 'whiteOutline' | 'black' | 'automatic'
518
+
519
+ onPress: () => void
520
+ style?: ViewStyle
521
+ }
522
+ ```
523
+
524
+ ##### Example
525
+
526
+ ```typescript
527
+ <ApplePayButton
528
+ buttonType="buy"
529
+ buttonStyle="black"
530
+ onPress={handlePayment}
531
+ style={{ width: '100%', height: 48 }}
532
+ />
533
+ ```
534
+
535
+ #### `GooglePayButton` (Android)
536
+
537
+ Native Google Pay button with customization.
538
+
539
+ ##### Props
540
+
541
+ ```typescript
542
+ interface GooglePayButtonProps {
543
+ buttonType?:
544
+ | 'buy'
545
+ | 'book'
546
+ | 'checkout'
547
+ | 'donate'
548
+ | 'order'
549
+ | 'pay'
550
+ | 'subscribe'
551
+ | 'plain'
552
+
553
+ theme?: 'dark' | 'light'
554
+
555
+ radius?: number // Corner radius in dp
556
+
557
+ onPress: () => void
558
+ style?: ViewStyle
559
+ }
560
+ ```
561
+
562
+ ##### Example
563
+
564
+ ```typescript
565
+ <GooglePayButton
566
+ buttonType="buy"
567
+ theme="dark"
568
+ radius={8}
569
+ onPress={handlePayment}
570
+ style={{ width: '100%', height: 48 }}
571
+ />
572
+ ```
573
+
574
+ ---
575
+
576
+ ### Utility Functions
577
+
578
+ #### `createPaymentRequest(config)`
579
+
580
+ Create a complete payment request from simplified config.
581
+
582
+ ```typescript
583
+ import { createPaymentRequest } from '@gmisoftware/react-native-pay'
584
+
585
+ const request = createPaymentRequest({
586
+ merchantIdentifier: 'merchant.com.example',
587
+ amount: 29.99,
588
+ label: 'Coffee Subscription',
589
+ countryCode: 'US',
590
+ currencyCode: 'USD',
591
+ googlePayEnvironment: 'TEST',
592
+ googlePayGateway: 'stripe',
593
+ googlePayGatewayMerchantId: 'your_merchant_id',
594
+ })
595
+ ```
596
+
597
+ #### `createPaymentItem(label, amount, type)`
598
+
599
+ Create a payment item.
600
+
601
+ ```typescript
602
+ import { createPaymentItem } from '@gmisoftware/react-native-pay'
603
+
604
+ const item = createPaymentItem('Subscription', 29.99, 'final')
605
+ // { label: 'Subscription', amount: 29.99, type: 'final' }
606
+ ```
607
+
608
+ #### `calculateTotal(items)`
609
+
610
+ Calculate total from payment items.
611
+
612
+ ```typescript
613
+ import { calculateTotal } from '@gmisoftware/react-native-pay'
614
+
615
+ const items = [
616
+ { label: 'Product', amount: 29.99, type: 'final' },
617
+ { label: 'Tax', amount: 2.4, type: 'final' },
618
+ ]
619
+
620
+ const total = calculateTotal(items) // 32.39
621
+ ```
622
+
623
+ #### `formatNetworkName(network)`
624
+
625
+ Format card network name for display.
626
+
627
+ ```typescript
628
+ import { formatNetworkName } from '@gmisoftware/react-native-pay'
629
+
630
+ formatNetworkName('visa') // "Visa"
631
+ formatNetworkName('mastercard') // "Mastercard"
632
+ formatNetworkName('amex') // "American Express"
633
+ ```
634
+
635
+ ---
636
+
637
+ ## TypeScript Types
638
+
639
+ ### Core Types
640
+
641
+ ```typescript
642
+ // Payment Item
643
+ interface PaymentItem {
644
+ label: string
645
+ amount: number
646
+ type: 'final' | 'pending'
647
+ }
648
+
649
+ // Payment Request
650
+ interface PaymentRequest {
651
+ merchantIdentifier: string
652
+ merchantName?: string
653
+ countryCode: string
654
+ currencyCode: string
655
+ paymentItems: PaymentItem[]
656
+ merchantCapabilities: string[]
657
+ supportedNetworks: string[]
658
+ shippingType?: string
659
+ shippingMethods?: PaymentItem[]
660
+ billingContactRequired?: boolean
661
+ shippingContactRequired?: boolean
662
+ // Google Pay specific
663
+ googlePayEnvironment?: 'TEST' | 'PRODUCTION'
664
+ googlePayGateway?: string
665
+ googlePayGatewayMerchantId?: string
666
+ }
667
+
668
+ // Payment Result
669
+ interface PaymentResult {
670
+ success: boolean
671
+ transactionId?: string
672
+ token?: PaymentToken
673
+ error?: string
674
+ }
675
+
676
+ // Payment Token
677
+ interface PaymentToken {
678
+ paymentMethod: PaymentMethod
679
+ transactionIdentifier: string
680
+ paymentData: string // Base64 encoded
681
+ }
682
+
683
+ // Payment Method
684
+ interface PaymentMethod {
685
+ displayName?: string
686
+ network?: PaymentNetwork
687
+ type: PaymentMethodType
688
+ secureElementPass?: PKSecureElementPass
689
+ billingAddress?: CNContact
690
+ }
691
+
692
+ // Payment Networks
693
+ type PaymentNetwork =
694
+ | 'visa'
695
+ | 'mastercard'
696
+ | 'amex'
697
+ | 'discover'
698
+ | 'jcb'
699
+ | 'maestro'
700
+ | 'electron'
701
+ | 'elo'
702
+ | 'idcredit'
703
+ | 'interac'
704
+ | 'privateLabel'
705
+
706
+ // Payment Method Type
707
+ type PaymentMethodType = 'unknown' | 'debit' | 'credit' | 'prepaid' | 'store'
708
+ ```
709
+
710
+ ### Contact Types
711
+
712
+ ```typescript
713
+ interface CNContact {
714
+ identifier: string
715
+ contactType: 'person' | 'organization'
716
+ namePrefix: string
717
+ givenName: string
718
+ middleName: string
719
+ familyName: string
720
+ previousFamilyName: string
721
+ nameSuffix: string
722
+ nickname: string
723
+ organizationName: string
724
+ departmentName: string
725
+ jobTitle: string
726
+ phoneticGivenName: string
727
+ phoneticMiddleName: string
728
+ phoneticFamilyName: string
729
+ phoneticOrganizationName?: string
730
+ note: string
731
+ imageDataAvailable?: boolean
732
+ phoneNumbers: CNLabeledPhoneNumber[]
733
+ emailAddresses: CNLabeledEmailAddress[]
734
+ postalAddresses: CNLabeledPostalAddress[]
735
+ }
736
+
737
+ interface CNPostalAddress {
738
+ street?: string
739
+ city?: string
740
+ state?: string
741
+ postalCode?: string
742
+ country?: string
743
+ isoCountryCode?: string
744
+ }
745
+ ```
746
+
747
+ ---
748
+
749
+ ## Advanced Usage
750
+
751
+ ### Manual Payment Flow (Without Hook)
752
+
753
+ For advanced use cases where you need more control:
754
+
755
+ ```typescript
756
+ import {
757
+ HybridPaymentHandler,
758
+ createPaymentRequest,
759
+ ApplePayButton,
760
+ GooglePayButton,
761
+ } from '@gmisoftware/react-native-pay'
762
+ import { Platform } from 'react-native'
763
+
764
+ // 1. Check availability
765
+ const status = HybridPaymentHandler.payServiceStatus()
766
+ if (!status.canMakePayments) {
767
+ console.log('Payment not available')
768
+ return
769
+ }
770
+
771
+ // 2. Create payment request
772
+ const paymentRequest = createPaymentRequest({
773
+ merchantIdentifier: 'merchant.com.example',
774
+ amount: 99.99,
775
+ label: 'Premium Subscription',
776
+ countryCode: 'US',
777
+ currencyCode: 'USD',
778
+ googlePayEnvironment: 'PRODUCTION',
779
+ googlePayGateway: 'stripe',
780
+ googlePayGatewayMerchantId: 'your_merchant_id',
781
+ })
782
+
783
+ // 3. Handle payment
784
+ const handlePayment = async () => {
785
+ try {
786
+ const result = await HybridPaymentHandler.startPayment(paymentRequest)
787
+
788
+ if (result.success && result.token) {
789
+ // Send to your server
790
+ await processPaymentOnServer(result.token)
791
+ } else {
792
+ console.error('Payment failed:', result.error)
793
+ }
794
+ } catch (error) {
795
+ console.error('Payment error:', error)
796
+ }
797
+ }
798
+
799
+ // 4. Render button
800
+ return Platform.OS === 'ios' ? (
801
+ <ApplePayButton
802
+ buttonType="subscribe"
803
+ buttonStyle="black"
804
+ onPress={handlePayment}
805
+ />
806
+ ) : (
807
+ <GooglePayButton
808
+ buttonType="subscribe"
809
+ theme="dark"
810
+ onPress={handlePayment}
811
+ />
812
+ )
813
+ ```
814
+
815
+ ### Dynamic Cart Management
816
+
817
+ ```typescript
818
+ const checkout = usePaymentCheckout({
819
+ merchantIdentifier: 'merchant.com.example',
820
+ currencyCode: 'USD',
821
+ })
822
+
823
+ // Add items dynamically
824
+ const handleAddToCart = (product) => {
825
+ checkout.addItem(product.name, product.price)
826
+ }
827
+
828
+ // Update quantity
829
+ const handleUpdateQuantity = (index, quantity) => {
830
+ const item = checkout.items[index]
831
+ checkout.updateItem(index, {
832
+ amount: item.amount * quantity,
833
+ })
834
+ }
835
+
836
+ // Apply discount
837
+ const handleApplyDiscount = (discountPercent) => {
838
+ const discountAmount = checkout.total * (discountPercent / 100)
839
+ checkout.addItem('Discount', -discountAmount, 'final')
840
+ }
841
+
842
+ // Clear cart
843
+ const handleClearCart = () => {
844
+ checkout.clearItems()
845
+ }
846
+ ```
847
+
848
+ ### Custom Payment Buttons
849
+
850
+ Create your own styled buttons:
851
+
852
+ ```typescript
853
+ import { Pressable, Text } from 'react-native'
854
+
855
+ function CustomPayButton({ onPress }) {
856
+ return (
857
+ <Pressable
858
+ onPress={onPress}
859
+ style={{
860
+ backgroundColor: '#000',
861
+ padding: 16,
862
+ borderRadius: 8,
863
+ alignItems: 'center',
864
+ }}
865
+ >
866
+ <Text style={{ color: '#fff', fontWeight: 'bold' }}>
867
+ {Platform.OS === 'ios' ? ' Pay' : 'G Pay'}
868
+ </Text>
869
+ </Pressable>
870
+ )
871
+ }
872
+
873
+ // Use it
874
+ <CustomPayButton onPress={handlePayment} />
875
+ ```
876
+
877
+ ### Server-Side Processing
878
+
879
+ After receiving the payment token, process it on your server:
880
+
881
+ #### Node.js + Stripe Example
882
+
883
+ ```javascript
884
+ // Backend API endpoint
885
+ app.post('/process-payment', async (req, res) => {
886
+ const { token } = req.body
887
+
888
+ try {
889
+ // For Apple Pay
890
+ if (token.paymentData) {
891
+ const charge = await stripe.charges.create({
892
+ amount: 2999, // $29.99
893
+ currency: 'usd',
894
+ source: token.paymentData, // Apple Pay token
895
+ description: 'Payment from React Native Pay',
896
+ })
897
+ }
898
+
899
+ // For Google Pay
900
+ // The token format depends on your gateway
901
+
902
+ res.json({ success: true, chargeId: charge.id })
903
+ } catch (error) {
904
+ res.status(500).json({ error: error.message })
905
+ }
906
+ })
907
+ ```
908
+
909
+ ---
910
+
911
+ ## Architecture
912
+
913
+ ### Package Structure
914
+
915
+ ```
916
+ @gmisoftware/react-native-pay/
917
+ ├── android/ # Android implementation
918
+ │ ├── src/main/java/com/margelo/nitro/pay/
919
+ │ │ ├── Constants.kt # Shared constants
920
+ │ │ ├── GooglePayButtonFactory.kt # Button factory
921
+ │ │ ├── GooglePayRequestBuilder.kt # Request builder
922
+ │ │ ├── HybridGooglePayButton.kt # Button component
923
+ │ │ ├── HybridPaymentHandler.kt # Payment handler
924
+ │ │ └── PaymentMapper.kt # Data transformation
925
+ │ ├── build.gradle
926
+ │ └── CMakeLists.txt
927
+
928
+ ├── ios/ # iOS implementation
929
+ │ ├── ApplePayButtonFactory.swift # Button factory
930
+ │ ├── HybridApplePayButton.swift # Button component
931
+ │ ├── HybridPaymentHandler.swift # Payment handler
932
+ │ └── PassKitTypeMapper.swift # Type conversion
933
+
934
+ ├── src/ # TypeScript source
935
+ │ ├── specs/ # Nitro specifications
936
+ │ │ ├── ApplePayButton.nitro.ts
937
+ │ │ ├── GooglePayButton.nitro.ts
938
+ │ │ └── PaymentHandler.nitro.ts
939
+ │ ├── types/ # Type definitions
940
+ │ │ ├── Contact.ts # Contact types
941
+ │ │ ├── Payment.ts # Payment types
942
+ │ │ └── index.ts
943
+ │ ├── utils/ # Utilities
944
+ │ │ ├── paymentHelpers.ts
945
+ │ │ └── index.ts
946
+ │ ├── hooks/ # React hooks
947
+ │ │ ├── usePaymentCheckout.ts
948
+ │ │ └── index.ts
949
+ │ ├── plugin/ # Expo config plugins
950
+ │ │ ├── withApplePay.ts
951
+ │ │ ├── withGooglePay.ts
952
+ │ │ └── index.ts
953
+ │ └── index.ts # Public API
954
+
955
+ ├── nitrogen/ # Generated code
956
+ │ └── generated/
957
+ │ ├── android/
958
+ │ ├── ios/
959
+ │ └── shared/
960
+
961
+ └── package.json
962
+ ```
963
+
964
+ ### Design Principles
965
+
966
+ 1. **Platform Abstraction** - Single API for both iOS and Android
967
+ 2. **Type Safety** - Full TypeScript coverage with runtime validation
968
+ 3. **Performance** - Built with Nitro Modules for native speed
969
+ 4. **Developer Experience** - Simple hooks API with sensible defaults
970
+ 5. **Production Ready** - Battle-tested in real-world applications
971
+
972
+ ---
973
+
974
+ ## Troubleshooting
975
+
976
+ ### iOS Issues
977
+
978
+ #### Apple Pay button not showing
979
+
980
+ - Verify merchant ID is correctly configured in Apple Developer Portal
981
+ - Check that entitlements are properly set in your Xcode project
982
+ - Ensure you've run `npx expo prebuild --clean`
983
+ - Test on a real device (Simulator requires additional setup)
984
+
985
+ #### "Cannot make payments" error
986
+
987
+ - Add a card to Apple Wallet on your test device
988
+ - Verify your merchant ID matches exactly
989
+ - Check that Apple Pay is enabled in Settings > Wallet & Apple Pay
990
+
991
+ ### Android Issues
992
+
993
+ #### Google Pay button not showing
994
+
995
+ - Verify Google Pay is enabled in your AndroidManifest.xml
996
+ - Check that `enableGooglePay: true` is set in your plugin config
997
+ - Ensure Google Play Services is installed on the device
998
+ - Test with a real device (Emulator needs Google Play Services)
999
+
1000
+ #### "Google Pay unavailable" error
1001
+
1002
+ - Add a card to Google Pay on your test device
1003
+ - For testing, use `googlePayEnvironment: 'TEST'`
1004
+ - Verify your gateway configuration is correct
1005
+
1006
+ ### General Issues
1007
+
1008
+ #### Build errors with Nitro
1009
+
1010
+ ```bash
1011
+ # Clean and reinstall
1012
+ rm -rf node_modules
1013
+ rm -rf ios/Pods ios/build
1014
+ rm -rf android/build android/app/build
1015
+ npm install
1016
+ cd ios && pod install
1017
+ ```
1018
+
1019
+ #### Type errors
1020
+
1021
+ ```bash
1022
+ # Regenerate types
1023
+ cd package
1024
+ npm run typescript
1025
+ npm run specs
1026
+ ```
1027
+
1028
+ ---
1029
+
1030
+ ## Examples
1031
+
1032
+ Check out the `/example` directory for a complete working implementation with:
1033
+
1034
+ - Full checkout flow
1035
+ - Cart management
1036
+ - Error handling
1037
+ - Platform-specific UI
1038
+
1039
+ Run the example:
1040
+
1041
+ ```bash
1042
+ cd example
1043
+ npm install
1044
+ npx expo prebuild
1045
+ npx expo run:ios
1046
+ npx expo run:android
1047
+ ```
1048
+
1049
+ ---
1050
+
1051
+ ## Contributing
1052
+
1053
+ We welcome contributions! Please follow these guidelines:
1054
+
1055
+ ### Development Setup
1056
+
1057
+ ```bash
1058
+ # Clone the repository
1059
+ git clone https://github.com/gmi-software/react-native-pay.git
1060
+ cd react-native-pay
1061
+
1062
+ # Install dependencies
1063
+ npm install
1064
+ cd package && npm install
1065
+
1066
+ # Generate Nitro bindings
1067
+ cd package
1068
+ npm run specs
1069
+ ```
1070
+
1071
+ ### Code Style
1072
+
1073
+ - Follow existing TypeScript patterns
1074
+ - Add JSDoc comments for public APIs
1075
+ - Use Prettier for formatting (runs automatically)
1076
+ - Ensure types are properly exported
1077
+
1078
+ ### Testing
1079
+
1080
+ - Test on both iOS and Android
1081
+ - Test with real devices (Simulator/Emulator support limited)
1082
+ - Verify in both TEST and PRODUCTION modes
1083
+
1084
+ ### Pull Requests
1085
+
1086
+ - Create a feature branch from `main`
1087
+ - Write descriptive commit messages
1088
+ - Update documentation for API changes
1089
+ - Add examples for new features
1090
+
1091
+ ---
1092
+
1093
+ ## Roadmap
1094
+
1095
+ - [ ] Recurring payment support
1096
+ - [ ] Shipping address collection
1097
+ - [ ] Multi-currency support
1098
+ - [ ] Payment request validation
1099
+ - [ ] Automated testing suite
1100
+ - [ ] Detailed transaction logging
1101
+ - [ ] Web support (via Payment Request API)
1102
+
1103
+ ---
1104
+
1105
+ ## License
1106
+
1107
+ MIT © [GMI Software](https://gmi.software)
1108
+
1109
+ ---
1110
+
1111
+ ## Credits
1112
+
1113
+ - Built with [Nitro Modules](https://nitro.margelo.com/) by [Margelo](https://margelo.com/)
1114
+ - Developed by [GMI Software](https://gmi.software)
1115
+
1116
+ ---
1117
+
1118
+ ## Support
1119
+
1120
+ - 📧 Email: [support@gmi.software](mailto:support@gmi.software)
1121
+ - 🐛 Issues: [GitHub Issues](https://github.com/gmi-software/react-native-pay/issues)
1122
+ - 💬 Discussions: [GitHub Discussions](https://github.com/gmi-software/react-native-pay/discussions)
1123
+
1124
+ ---
1125
+
1126
+ <div align="center">
1127
+
1128
+ Made with ❤️ by [GMI Software](https://gmi.software)
1129
+
1130
+ </div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gmisoftware/react-native-pay",
3
- "version": "0.0.10",
3
+ "version": "0.0.11",
4
4
  "author": "gmi.software",
5
5
  "repository": {
6
6
  "type": "git",
@@ -103,6 +103,8 @@
103
103
  },
104
104
  "react-native": "src/index",
105
105
  "scripts": {
106
+ "prepack": "cp ../README.md ./README.md",
107
+ "postpack": "rm ./README.md",
106
108
  "postinstall": "tsc || exit 0;",
107
109
  "typecheck": "tsc --noEmit",
108
110
  "clean": "rm -rf android/build node_modules/**/android/build lib",