Создание пользовательской формы оплаты с использованием React и Square
Есть много способов принимать платежи онлайн. Разве не было бы неплохо реализовать одну форму, которая могла бы принимать столько способов оплаты, сколько мы хотим? Давайте посмотрим на реализацию пользовательской формы оплаты с использованием Square и React . Эта форма позволит нам принимать кредитные карты через Интернет и предоставлять поддержку Apple Pay, Google Pay и Masterpass в единой форме оплаты.
Требования
- Реагировать (упрощенно
create-react-app
). - Квадратная форма оплаты .
Наша окончательная (платежная) форма:
Реакция и Квадратная форма оплаты
Если вы знакомы с React, то вы привыкли передавать props
и управлять своим компонентом через него state
. Давайте сосредоточимся на том, как настроить базовую настройку и запустить ее с помощью платежной формы Square, управляемой компонентом React.
Мы также продемонстрируем, как динамически загружать скрипт формы оплаты Square, если вы хотите просто вставить компонент формы оплаты на страницу. Динамическая загрузка скрипта актуальна только в том случае, если вы не хотите, чтобы скрипт загружался только на странице оформления заказа (или там, где вы хотите принять платеж).
Вам также может понравиться:
Как изучить React.js, Часть 1: Дорожная карта React для современных веб-разработчиков .
Если вы не знакомы с формой оплаты Square, отправляйтесь в документы и ознакомьтесь. Есть несколько шаблонов, объяснений и руководств по настройке формы с использованием базового HTML, CSS и JavaScript.
На базовом уровне форма оплаты напрямую фиксирует данные карты вашего клиента непосредственно на серверах Square с помощью <iframe>
. Форма оплаты облегчает генерацию этих <iframe>
элементов и предоставляет API для создания одноразового номера ( одноразового токена) для последующего обращения к этим деталям (и все это без знания какой-либо конфиденциальной информации!).
Основная проблема, с которой вы сталкиваетесь, когда эти <iframe>
элементы заменяют другие элементы в DOM, заключается в том, что React обычно любит отвечать за все взаимодействия с DOM. Это требует дополнительной настройки наших компонентов, чтобы быть уверенным, что мы отображаем все правильно (в правильном порядке) и правильно обрабатываем различные события, генерируемые скриптом формы платежа Square.
Динамически загружать квадратный скрипт формы оплаты
Наш базовый компонент — это то, где мы на самом деле управляем динамической загрузкой:
<script src=”https://js.squareup.com/v2/paymentform”></script>
в <head>
DOM, чтобы вызвать рендеринг нашего дочернего компонента. Дочерний компонент будет фактически отвечать за сборку, форматирование и управление нашей формой оплаты. Это сделано для того, чтобы скрипт был загружен, чтобы мы могли передать SqPaymentForm
объект нашему дочернему компоненту.
JavaScript
1
импортировать React , { Component } из 'response' ;
2
импортировать PaymentForm из './components/PaymentForm' ;
3
Класс App расширяет Компонент {
5
конструктор ( реквизит ) {
6
супер ( реквизит )
7
8
это . состояние = {
9
загружен : ложь
10
}
11
}
12
13
componentWillMount () {
14
const that = this ;
15
пусть sqPaymentScript = документ . createElement ( 'script' );
16
17
sqPaymentScript . src = "https://js.squareup.com/v2/paymentform" ;
18
sqPaymentScript . type = "text / javascript" sqPaymentScript . async = false ;
19
sqPaymentScript . onload = () => {
20
это . setState ({
21
загружен : правда
22
})
23
};
24
25
документ . getElementsByTagName ( "head" ) [ 0 ]. appendChild ( sqPaymentScript );
26
}
27
28
render () {
29
возврат (
30
это . состояние . загружен && < PaymentForm paymentForm = { окно . SqPaymentForm } />
31
);
32
}
33
}
34
приложение по умолчанию для экспорта ;
36
Вы можете видеть, что мы просто используем некоторый ванильный JavaScript внутри метода жизненного цикла, componentWillMount()
чтобы создать <script>
элемент и установить некоторые атрибуты. Затем мы проверяем, что мы обновляем состояние нашего компонента React до того loaded
момента, когда скрипт действительно загрузится на страницу. Этот триггер отреагирует повторный рендеринг и возврат true
для this.state.loaded
внутри нашего render()
метода и позволяет наш ребенок компонент для визуализации.
Другая заметная часть нашего кода - то, как мы проходим SqPaymentForm
через paymentForm
опору. Мы передаем объект SqPaymentForm, который прикреплен к окну, поэтому управление рендерингом формы оплаты и инициирование отправки проще. Полный пример кода также можно найти в этом репо.
Реагировать Компонент формы оплаты
Для простоты мы модифицируем существующие шаблоны, найденные в Square GitHub . Для получения дополнительной информации о настройке или настройке формы оплаты Square, ознакомьтесь с нашими руководствами . Мы сосредоточимся больше на разнице между этими шаблонами и подключением элементов к нашему компоненту React.
Наш метод render ()
JavaScript
xxxxxxxxxx
1
render () {
2
возврат (
3
< div className = "container" >
4
< div id = "form-container" >
5
< div id = "sq-walletbox" >
6
кнопка <
7
style = {{ display : ( this . state . applePay ) ? 'наследовать' : 'нет' }
8
className = "кнопка-кошелек"
9
id = "sq-apple-pay" >
10
< / button>
11
кнопка <
12
style = {{ display : ( this . state . masterpass ) ? 'block' : 'none' }}
13
className = "wallet-button" id = "sq-masterpass" >
14
< / button>
15
кнопка <
16
style = {{ display : ( this . state . googlePay ) ? 'наследовать' : 'нет' }}
17
className = "wallet-button" id = "sq-google-pay" >
18
< / button>
19
< ч />
20
< / div>
21
< div id = "sq-ccbox" >
22
< p >
23
< span style = { styles . leftCenter } > Введите информацию о карте ниже < / span
24
< span style = { styles . blockRight
25
{ это . состояние . cardBrand . toUpperCase ()}
26
< / span>
27
< / p>
28
< div id = "cc-field-wrapper" >
29
< div id = "sq-card-number" > < / div>
30
< input type = "hidden" id = "card-nonce" name = "nonce" />
31
< div id = "sq-expiration-date" > < / div>
32
< div id = "sq-cvv" > < / div>
33
< / div>
34
< input id = "name" style = { styles . name } type = "text" placeholder = "Имя" />
35
< div id = "sq-postal-code" > < / div>
36
< / div>
37
кнопка <
38
className = "кнопка-кредитная карта"
39
onClick = { это . requestCardNonce }
40
> Оплатить < / button>
41
< / div>
42
< p style = { styles . center } id = "error" > < / p>
43
< / div>
44
)
45
}
Основные части к записке в элементах мы имеем являются дивы элементы с идентификаторами: sq-apple-pay
, sq-masterpass
, sq-google-pay
, sq-card-number
, sq-cvv
, sq-expiration-date
, и sq-postal-code
. Мы преобразовали примеры, чтобы использовать div для всего, а не для компонентов формы, так как это все поля, для которых сценарий платежной формы Square будет заменен <iframe>
элементами. Кроме того, поскольку мы используем React, у нас будут свои собственные функции для контроля отправки и запуска запроса одноразового номера из формы оплаты.
Цифровые кошельки и поддерживаемые платежи
Чтобы настроить параметры цифрового кошелька ( иногда называемые параметрами мобильного кошелька ), которые вы хотите поддерживать, просто предоставьте различные пары ключ-значение в SqPaymentForm
объекте конфигурации ( подробнее об этом здесь ). Вы должны увидеть render()
способ, которым мы контролируем отображение наших вариантов мобильных платежей с помощью компонента state
.
JavaScript
xxxxxxxxxx
1
обратные вызовы : {
2
methodSupported : ( методы ) => {
3
if ( методов . googlePay ) {
4
это . setState (
5
{ googlePay : методы . googlePay }
6
)
7
}
8
9
if ( методы . applePay ) {
10
это . setState ({
11
ApplePay : методы . applePay
12
})
13
}
14
15
if ( методы . masterpass ) {
16
это . setState ({
17
masterpass : методы . masterpass
18
})
19
}
20
21
возврат ;
22
},
23
Мы устанавливаем состояние внутри функции methodsSupported()
обратного вызова, которую нам предоставила форма оплаты Square. Поскольку каждый параметр мобильного кошелька зависит от браузера, из которого посещает клиент, вам необходимо условно отобразить кнопки в соответствии с тем, что должно быть доступно, на основе браузера вашего клиента или мобильного устройства.
Мы также должны сделать эти отдельные условия, так как форма оплаты вызывает methodsSupport()
функцию один раз для каждого метода, который вы выбираете для поддержки. Наш пример пытается поддерживать Masterpass, Apple Pay и Google Pay, поэтому будет сделано три звонка. Это немного агрессивно в наших вызовах setState()
, но только три вызова, так что не беспокойтесь - просто помните об этом, если вы звоните в setState()
другое место, так как каждый вызов будет вызывать повторную визуализацию компонента.
Связывание и управление компонентом
The main takeaway is to use state
inside of the provided callback. Using state
in the component allows us to react (so punny) to different events emitted by Square’s payment form script. You can learn more about all these events are in the docs. In our example, a key place for this tie-in would be the inputEventReceived()
callback since it’s called on every input event. In our example component, we update the brand of the card (in the top right corner) once it has been identified by the payment form.
Thoughts and Conclusions
This is only one way of approaching implementing the Square payment form in React. Initially, it seemed like a good idea to try passing in the config object as a prop, but that doesn’t work too well for configuring your callback functions, unless you’re comfortable overriding them before creating your paymentForm
object (this just felt wrong).
The main place I’ve seen developers trip up is usually on not disabling autoBuild
. The paymentform
script is going to immediately look for elements with the provided element id’s on build, but React might not have rendered the elements to the DOM yet. (You can see how this could be an issue.) It is better to control the build process by triggering it with a call to.build()
.
The implementation of the form in React is fairly straight forward (if you know React) and just requires understanding React lifecycle in relation to the paymentform
lifecycle.
You can find a full example of this form over at: https://github.com/mootrichard/square-react-online-payments.
If you liked this post on React + Square, but would like to see this refactored using React’s Hooks API, tweet at me, respond here on DZone, or bug me in our Slack community, and I’ll follow up with a post with how to refactor this example using the React Hooks API.