Terima pembayaran kartu tanpa webhook
Pelajari cara mengonfirmasi pembayaran kartu di server Anda dan menangani permintaan autentikasi kartu.
Untuk pemeriksaan di masa mendatang dan dukungan yang lebih luas, gunakan integrasi standar untuk pembayaran asinkron.
Integrasi ini menggunakan satu alur client-ke-server untuk menerima pembayaran, tanpa menggunakan webhook atau memproses kejadian offline. Meski terlihat lebih sederhana, integrasi ini sulit ditingkatkan skalanya seiring dengan bertumbuhnya bisnis Anda dan beberapa keterbatasan yang dimilikinya:
- Hanya mendukung kartu—Anda harus menulis lebih banyak kode untuk mendukung metode pembayaran regional yang populer dan ACH secara terpisah.
- Risiko charge dua kali lipat—Dengan membuat PaymentIntent baru secara sinkron setiap kali pelanggan mencoba membayar, Anda berisiko men-charge pelanggan dua kali lipat secara tidak sengaja. Pastikan untuk mengikuti praktik terbaik.
- Penanganan autentikasi manual—Kartu dengan 3D Secure atau yang tunduk pada regulasi, seperti Autentikasi Pelanggan yang Kuat, memerlukan langkah ekstra di client.
Pertimbangkan batasan ini jika Anda memutuskan untuk menggunakan integrasi ini. Jika tidak, gunakan integrasi standar.
Siapkan StripeSisi serverSisi client
Sisi server
Integrasi ini memerlukan endpoint di server Anda yang berbicara dengan API Stripe. Gunakan pustaka resmi kami untuk akses ke API Stripe dari server Anda:
Sisi client
React Native SDK adalah sumber terbuka dan didokumentasikan lengkap. Secara internal, SDK iOS asli dan SDK Android digunakan. Untuk menginstal React Native SDK Stripe, jalankan salah satu perintah berikut di direktori proyek (bergantung pada manajer paket yang Anda gunakan):
Selanjutnya, instal beberapa dependensi lain yang diperlukan:
- Untuk iOS, navigasikan ke direktori ios dan jalankan
pod install
untuk memastikan bahwa Anda juga menginstal dependensi asli yang diperlukan. - Untuk Android, tidak ada lagi ketergantungan yang harus diinstal.
Catatan
Sebaiknya ikuti panduan TypeScript resmi untuk menambahkan dukungan TypeScript.
Inisialisasi Stripe
Untuk menginisialisasi Stripe di aplikasi React Native, bungkus layar pembayaran dengan komponen StripeProvider
, atau gunakan metode inisialisasi initStripe
. Hanya kunci yang dapat dipublikasikan API di publishableKey
yang diperlukan. Contoh berikut menunjukkan cara menginisialisasi Stripe menggunakan komponen StripeProvider
.
import { useState, useEffect } from 'react'; import { StripeProvider } from '@stripe/stripe-react-native'; function App() { const [publishableKey, setPublishableKey] = useState(''); const fetchPublishableKey = async () => { const key = await fetchKey(); // fetch key from your server here setPublishableKey(key); }; useEffect(() => { fetchPublishableKey(); }, []); return ( <StripeProvider publishableKey={publishableKey} merchantIdentifier="merchant.identifier" // required for Apple Pay urlScheme="your-url-scheme" // required for 3D Secure and bank redirects > {/* Your app code here */} </StripeProvider> ); }
Catatan
Gunakan kunci percobaan API Anda saat mencoba serta mengembangkan, dan kunci mode live bila Anda memublikasikan aplikasi.
Buat halaman checkout AndaSisi client
Kumpulkan informasi kartu dengan aman pada client dengan CardField
, yakni komponen UI yang disediakan oleh SDK yang mengumpulkan nomor kartu, tanggal kedaluwarsa, CVC, dan kode pos
CardField
melakukan validasi dan pemformatan secara aktual.
Tambahkan komponen CardField
ke layar pembayaran Anda untuk mengumpulkan detail kartu dengan aman dari pelanggan. Gunakan callback onCardChange
untuk memeriksa informasi nonsensitif tentang kartu, seperti merek, dan apakah detailnya sudah lengkap.
import { CardField, useStripe } from '@stripe/stripe-react-native'; function PaymentScreen() { // ... return ( <View> <CardField postalCodeEnabled={true} placeholders={{ number: '4242 4242 4242 4242', }} cardStyle={{ backgroundColor: '#FFFFFF', textColor: '#000000', }} style={{ width: '100%', height: 50, marginVertical: 30, }} onCardChange={(cardDetails) => { console.log('cardDetails', cardDetails); }} onFocus={(focusedField) => { console.log('focusField', focusedField); }} /> </View> ); }
Jalankan aplikasi Anda, dan pastikan halaman checkout Anda menampilkan komponen CardField
.
Kumpulkan detail kartuSisi client
Bila pelanggan Anda siap untuk melakukan checkout, buat PaymentMethod dengan detail yang dikumpulkan oleh komponen CardField
.
import { CardField, useStripe } from '@stripe/stripe-react-native'; function PaymentScreen() { const { createPaymentMethod, handleNextAction } = useStripe(); const pay = () => { // Gather customer billing information (for example, email) const billingDetails: CreatePaymentMethod.BillingDetails = { email: 'email@stripe.com', phone: '+48888000888', addressCity: 'Houston', addressCountry: 'US', addressLine1: '1459 Circle Drive', addressLine2: 'Texas', addressPostalCode: '77063', }; // Create payment method const { paymentMethod, error } = await createPaymentMethod({ paymentMethodType: 'Card', paymentMethodData: { billingDetails, } }); }; // ... }
Serahkan PaymentMethod ke server AndaSisi client
Jika PaymentMethod berhasil dibuat, kirim identifikasinya ke server Anda.
// ... const pay = () => { // ... // Send the PaymentMethod to your server to create a PaymentIntent const response = await fetch(`/pay`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ paymentMethodId: paymentMethod.id }), }); const { error, requires_action, payment_intent_client_secret } = await response.json(); if (error) { // Error creating or confirming PaymentIntent Alert.alert('Error', paymentIntentError); return; } if (payment_intent_client_secret && !requires_action) { // Payment succeeded Alert.alert('Success', 'The payment was confirmed successfully!'); } if (payment_intent_client_secret && requires_action) { // ...continued below } }; // ...
Buat PaymentIntentSisi server
Siapkan endpoint di server Anda untuk menerima permintaan. Endpoint ini juga akan digunakan kemudian untuk menangani kartu yang membutuhkan langkah autentikasi tambahan.
Buat PaymentIntent baru dengan identifikasi PaymentMethod yang dibuat pada client Anda. Anda dapat mengonfirmasi PaymentIntent dengan mengatur properti confirm ke true bila PaymentIntent dibuat atau dengan memanggil confirm setelah pembuatan. Pisahkan otorisasi dan penarikan juga didukung untuk pembayaran kartu.
Jika pembayaran memerlukan tindakan tambahan, seperti autentikasi 3D Secure, status PaymentIntent akan diatur ke requires_
. Jika pembayaran gagal, status diatur kembali ke requires_
dan Anda harus menampilkan kesalahan kepada pengguna. Jika pembayaran tidak memerlukan autentikasi tambahan maka charge akan dibuat dan status PaymentIntent diatur ke succeeded
.
Catatan
Pada versi API sebelum 2019-02-11, requires_
muncul sebagai requires_
dan requires_
muncul sebagai requires_
.
Jika Anda ingin menyimpan kartu untuk digunakan kembali nanti, buat Customer untuk menyimpan PaymentMethod dan teruskan parameter tambahan berikut saat membuat PaymentIntent:
- customer. Diatur ke identifikasi Pelanggan.
- setup_future_usage. Atur ke
off_
untuk memberi tahu Stripe bahwa Anda berencana untuk menggunakan kembali PaymentMethod ini untuk pembayaran di luar sesi saat pelanggan Anda tidak ada. Mengatur properti ini akan menyimpan PaymentMethod ke Pelanggan setelah PaymentIntent dikonfirmasi dan setiap tindakan yang dibutuhkan dari pengguna telah selesai. Lihat sampel kode tentang menyimpan kartu setelah pembayaran untuk detail selengkapnya.session
Tangani tindakan berikutnyaSisi client
Pembayaran normal berhasil setelah Anda mengonfirmasikannya pada server di langkah 4. Namun, beberapa alur pembayaran memerlukan tindakan tambahan dari pelanggan, seperti melakukan autentikasi dengan 3D Secure.
Untuk kasus yang memerlukan tindakan berikutnya, status PaymentIntent adalah requires_
. Di client, teruskan client secret PaymentIntent ke handleNextAction
. Handler asli menyajikan tampilan dan memandu pelanggan melalui alur autentikasi. Setelah menangani tindakan yang diperlukan di client, status PaymentIntent berubah menjadi requires_
. Hal ini memungkinkan integrasi Anda memenuhi pesanan di backend dan mengembalikan hasil pemenuhan ke client Anda.
Kirim identifikasi PaymentIntent ke backend Anda dan konfirmasikan lagi dalam waktu satu jam untuk memfinalisasi pembayaran. Jika tidak maka upaya pembayaran gagal dan berubah kembali menjadi requires_
.
// ... const pay = () => { // ... // If PaymentIntent requires action, call handleNextAction if (payment_intent_client_secret && requires_action) { const { error, paymentIntent } = await handleNextAction(payment_intent_client_secret); if (error) { Alert.alert(`Error code: ${error.code}`, error.message); } else if (paymentIntent) { if ( paymentIntent.status === PaymentIntents.Status.RequiresConfirmation ) { // Confirm the PaymentIntent again on your server const response = await fetch(`/pay`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ payment_intent_id: paymentIntent.id }), }); const { error, success } = await response.json(); if (error) { // Error during confirming Intent Alert.alert('Error', error); } else if (success) { Alert.alert('Success', 'The payment was confirmed successfully!'); } } else { // Payment succedeed Alert.alert('Success', 'The payment was confirmed successfully!'); } } } }; // ...
Konfirmasikan lagi PaymentIntentSisi server
Kode ini hanya dieksekusi bila pembayaran memerlukan autentikasi tambahan—sama seperti penanganan di langkah sebelumnya. Kode ini sendiri tidak bersifat opsional karena pembayaran dapat memerlukan langkah ekstra ini.
Dengan menggunakan endpoint yang sama dengan yang Anda siapkan di di atas, konfirmasikan lagi PaymentIntent untuk memfinalisasi pembayaran dan penuhi pesanan. Pastikan konfirmasi ini terjadi dalam waktu satu jam sejak upaya pembayaran. Jika tidak, pembayaran akan gagal dan bertransisi kembali ke requires_
.
Coba integrasi
Beberapa kartu percobaan tersedia untuk Anda gunakan di sandbox guna memastikan integrasi ini siap. Gunakan bersama CVC dan tanggal kedaluwarsa di masa mendatang.
Nomor | Keterangan |
---|---|
Berhasil dan segera memproses pembayaran. | |
Memerlukan autentikasi. Stripe memicu modal yang meminta pelanggan untuk mengautentikasi. | |
Selalu gagal dengan kode tolakan insufficient_ . |
Untuk daftar lengkap kartu percobaan, lihat panduan kami mengenai percobaan.