Компонент Stripe ‹CardElement /› по умолчанию выглядит прилично и действительно прост в использовании, и по умолчанию принимает номер карты, срок действия и CVC в одной области ввода.
Однако некоторые макеты требуют, чтобы вы отделяли ввод CVC и срок действия от номера карты. Я начинаю это руководство с того момента, как уже завершил реализацию ‹CardElement /› (код приведен ниже). Тем не менее, я не вникаю в фактическую настройку чередования, например, установку библиотек чередования для реакции, получение обещания чередования или перенос провайдера ‹Elements /› на модальный компонент оплаты.
Вот код, который я написал для создания этого простого платежного модала:
const stripe = useStripe(); const elements = useElements(); const createSubscription = async () => { setLoading(true); try { // create a payment method const paymentMethod = await stripe?.createPaymentMethod({ type: "card", card: elements.getElement(CardElement), billing_details: { name: GlobalAppState.getUser().name, } }); } catch (error) { ZensoryModule.getErrorHandler().handleError(error); console.log(error); } } <div className="popup-container-payment" ref={modalRef}> <div className="popup-header"> <img id="btn-auth-error-popup-close" src={cross} className="popup-close-icon" onClick={(e) => closePopup(e)} alt="Close popup" tabIndex="0" onKeyDown={(e) => _handleKeyDownClose(e)} /> </div> <div className="popup-instruction-payment"> {getText(TextId.subscribePayment)} </div> <div className="card-entry"> <CardElement options={cardElementOptions} /> </div> {loading ? ( <div style={{ position: "relative", marginBottom: "40px", marginTop: "10px", }} > <SpinnerLoader /> </div> ) : ( <button disabled={!stripe || loading} id="btn-auth-error-popup-okay" tabIndex="0" className="subscribe-button" onClick={createSubscription} > Subscribe </button> )} <div> <img src={stripePower} alt="Powered by stripe" /> </div> </div>
Однако внешний вид, которого я хотел добиться, был (это дизайн):
Для этого нам нужно заменить ‹CardElement /› на ‹CardNumberElement /›, ‹CardExpiryElement /› и ‹CardCvcElement /›.
Обновленный код:
const stripe = useStripe(); const elements = useElements(); const createSubscription = async () => { setLoading(true); try { // create a payment method const paymentMethod = await stripe?.createPaymentMethod({ type: "card", card: elements.getElement(CardNumberElement), //please note this is changed from the original code billing_details: { name: GlobalAppState.getUser().name, } }); } catch (error) { ZensoryModule.getErrorHandler().handleError(error); console.log(error); } } <div className="popup-container-payment" ref={modalRef}> <div className="popup-header"> <img id="btn-auth-error-popup-close" src={cross} className="popup-close-icon" onClick={(e) => closePopup(e)} alt="Close popup" tabIndex="0" onKeyDown={(e) => _handleKeyDownClose(e)} /> </div> <div className="popup-instruction-payment"> {getText(TextId.subscribePayment)} </div> <div className="card-entry"> <CardNumberElement options={cardElementOptions} /> </div> <div className="expiry-cvc-entry"> <div className="card-entry"> <CardExpiryElement options={cardElementOptions} /> </div> <div className="card-entry"> <CardCvcElement options={cardElementOptions} /> </div> </div> {loading ? ( <div style={{ position: "relative", marginBottom: "40px", marginTop: "10px", }} > <SpinnerLoader /> </div> ) : ( <button disabled={!stripe || loading} id="btn-auth-error-popup-okay" tabIndex="0" className="subscribe-button" onClick={createSubscription} > Subscribe </button> )} <div> <img src={stripePower} alt="Powered by stripe" /> </div> </div>
Достигнутый результат:
Этот макет может быть просто требованием дизайна или выбором UX. На мой взгляд, он выглядит более профессионально, а также хорошо понятен пользователям.