@olo/pay-react-native
Version:
Olo Pay React Native SDK
998 lines (732 loc) • 104 kB
Markdown
# @olo/pay-react-native
## Table Of Contents
- [About Olo Pay](#about-olo-pay)
- [About the React Native SDK](#about-the-react-native-sdk)
- [Installation](#installation)
- [Getting Started](#getting-started)
- [Handling Promise Rejections](#handling-promise-rejections)
- [Events](#events)
- [Components](#components)
- [PaymentCardDetailsView](#paymentcarddetailsview)
- [PaymentCardDetailsForm](#paymentcarddetailsform)
- [PaymentCardCvvView](#paymentcardcvvview)
- [DigitalWalletButton](#digitalwalletbutton)
- [OloPaySDK Module](#olopaysdk-module)
- [Changelog](#changelog)
- [License](#license)
## About Olo Pay
[Olo Pay](https://www.olo.com/solutions/pay/) is an E-commerce payment solution designed to help restaurants grow, protect, and support their digital ordering and delivery business. Olo Pay is specifically designed for digital restaurant ordering to address the challenges and concerns that weʼve heard from thousands of merchants.
## About the React Native SDK
The Olo Pay React Native SDK allows partners to easily add PCI-compliant Apple Pay and Google Pay functionality to their checkout flow and seamlessly integrate with the Olo Ordering API.
Use of the plugin is subject to the terms of the [Olo Pay SDK License](#License).
For more information about integrating Olo Pay into your payment solutions, refer to our [Olo Pay Dev Portal Documentation](https://developer.olo.com/docs/load/olopay) _(Note: requires an Olo Developer account)_.
## Installation
### **_Important_:** If using [Expo](https://expo.dev/), be sure to [eject](https://docs.expo.dev/archive/glossary/#eject) or run [`npx expo prebuild`](https://docs.expo.dev/workflow/prebuild/) prior to installation
Run the following command from a terminal in your app's root project directory
```sh
npm install @olo/pay-react-native
```
### Android-Specific Install Steps
#### Supported Versions
- _Minimum SDK Version:_
- The minimum supported Android SDK is [API 24](https://developer.android.com/tools/releases/platforms#7.0)
- The Android project's `minSdkVersion` must be set to `24` or higher
- _Compile SDK Version:_
- The Olo Pay SDK is compiled against [API 35](https://developer.android.com/tools/releases/platforms#15)
- It is recommended to set the Android project's `compileSdkVersion` to `35` or higher
- _Gradle:_
- The SDK is built with Gradle `v8.11.1` and Android Gradle Plugin `v8.10.0`
- If the Android project does not compile, the Android Gradle Plugin and/or Gradle versions may need to be updated
#### Components
In order to use the `PaymentCardFormView` you need to install and configure [Material Components theme](https://github.com/material-components/material-components-android/blob/master/docs/getting-started.md#4-change-your-app-theme-to-inherit-from-a-material-components-theme) in your app.
1. In your `app/build.gradle` add the dependency with a specific version
```groovy
implementation 'com.google.android.material:material:<version>'
```
1. Set the appropriate style in your `styles.xml` file
```xml
<style name="Theme.MyApp" parent="Theme.MaterialComponents.DayNight">
<!-- ... -->
</style>
```
### iOS-Specific Install Steps
#### Supported Versions
- _Minimum iOS Version:_
- The minimum supported version is [iOS 14](https://support.apple.com/en-us/118390#14)
In you app's Podfile:
- Add the following lines at the top:
```Podspec
source 'https://github.com/CocoaPods/Specs.git'
source 'https://github.com/ololabs/podspecs.git'
```
- Ensure that `ios.developmentTarget` is set to at least `14.0`
Open a terminal, navigate to your app's iOS folder (usually `<projectName>/ios`), and run the following command:
```sh
pod install
```
## Updating From a Previous Version
Run the following command from a terminal in your app's root project directory
```sh
npm install @olo/pay-react-native@latest
```
### iOS-Specific Update Steps
Open a terminal, navigate to your app's iOS folder (usually `<projectName>/ios`), and run the following commands:
```sh
rm -rf Pods
pod update
```
> **Note:** If you run into errors after updating, delete both your `Pods` folder and `Podfile.lock` file and then run `pod install`.
### Known Issues
##### Versions up to 5.0.0
When passing incorrect or invalid parameters, error messages may refer to native platform-specific types that do not exist in JavaScript or Typescript (e.g. `Double` instead of `Number`).
##### Versions 2.0.0 Through 3.0.2
- [PaymentCardDetailsView](#paymentcarddetailsview): The following properties must be provided to prevent a crash: `cardStyles.errorTextColor`, `cardStyles.textColor`, and `cardStyles.placeholderColor`
- [PaymentCardCvvView](#paymentcardcvvview): The following properties must be provided to prevent a crash: `cvvStyles.errorTextColor`, `cvvStyles.textColor`, and `cvvStyles.placeholderColor`
[[Back to Top]](#table-of-contents)
## Getting Started
A basic high-level overview of the steps needed to integrate the React Native SDK into your hybrid app is as follows:
#### Payment Methods (new cards & digital wallets)
This approach is used for cards that have not previously been saved on file with Olo. This includes new credit cards and digital wallets. With this approach both card input components and digital wallets return a [PaymentMethod](#paymentmethod) instance that is then used to submit a basket with Olo's Ordering API. Specific details can be found below.
1. Initialize Olo Pay (see [`initialize(...)`](#initialize)).
2. Create the [PaymentMethod](#paymentmethod).
- Credit Card Components
1. Add a component to the App's UI (See [PaymentCardDetailsView](#paymentcarddetailsview) and [PaymentCardDetailsForm](#paymentcarddetailsform))
2. Use the `createPaymentMethod()` function on the component to get a [PaymentMethod](#paymentmethod) instance
- Digital Wallets _(Apple Pay & Google Pay)_
1. Wait for [`DigitalWalletReadyEvent`](#digitalwalletreadyevent) to indicate when digital wallet payments can be processed.
2. Create a payment method (see [`createDigitalWalletPaymentMethod(...)`](#createdigitalwalletpaymentmethod)).
3. Submit the order to [Olo's Ordering API](https://developer.olo.com/docs/load/olopay#section/Submitting-a-Basket-via-the-Ordering-API) using the [PaymentMethod](#paymentmethod) details.
#### CVV Tokens (previously saved cards)
This approach is used for cards that have previously been saved on file with Olo, and you want to reverify the CVV of the saved card prior to submitting a basket and processing a payment. The [PaymentCardCvvView](#paymentcardcvvview) component will provide a [CvvUpdateToken](#cvvupdatetoken) instance that is then used to submit a basket with Olo's Ordering API. Specific details can be found below.
1. Initialize Olo Pay (see [`initialize(...)`](#initialize)).
1. Create the [CvvUpdateToken](#cvvupdatetoken).
1. Add the [PaymentCardCvvView](#paymentcardcvvview) component to the App's UI.
1. Use the `createCvvUpdateToken()` function on the component to get a [CvvUpdateToken](#cvvupdatetoken) instance
1. Submit the order to [Olo's Ordering API](https://developer.olo.com/docs/load/olopay#section/Submitting-a-Basket-via-the-Ordering-API) using the [CvvUpdateToken](#cvvupdatetoken) details.
[[Back to Top]](#table-of-contents)
## Handling Promise Rejections
When calling functions on the Olo Pay React Native SDK, there is a chance that the call will fail with the promise being rejected. When this happens
the returned error object will always contain `code` and `message` properties indicating why the method call was rejected.
For convenience, the SDK exports a [`PromiseRejectionCode`](#promiserejectioncode) enum and a [`PromiseRejection`](#promiserejection) type for
handling promise rejection errors.
### Example
```typescript
try {
const paymentMethodData = await createDigitalWalletPaymentMethod({ amount: 2.34 }});
//Handle payment method data
} catch (error) {
let rejection = error as PromiseRejection;
if (rejection) {
switch(rejection.code) {
case PromiseRejectionCode.missingParameter: {
// Handle missing parameter scenario
break;
}
case PromiseRejectionCode.sdkUninitialized: {
// Handle sdk not initialized scenario
break;
}
}
} else {
// Some other error not related to a promise rejection
}
}
```
[[Back to Top]](#table-of-contents)
## Events
Events are used to send notifications regarding state changes that can't be completely handled by asynchronous method calls that return a promise. Details about each type of event can be found below.
#### DigitalWalletReadyEvent
You can subscribe to this event to know when digital wallets are ready to process payments. It can be referenced using the exported `DigitalWalletReadyEvent` constant or as a string with `"digitalWalletReadyEvent"`. The event returns a [`DigitalWalletStatus`](#digitalwalletstatus) object. Attempting to create a [PaymentMethod](#paymentmethod) via [createDigitalWalletPaymentMethod](#createdigitalwalletpaymentmethod) when digital wallets are not in a ready state will result in errors.
This event is emitted whenever the readiness of digital wallets change. It can change as a result of calling certain methods on the SDK (e.g. [initialize](#initialize) or [updateDigitalWalletConfig](#updatedigitalwalletconfig)) or due to changes in app state (e.g. app going in the background).
**_Important:_** This event can, and likely will, be emitted multiple times. It is recommended to keep this event listener active and update your UI accordingly whenever the app is displaying digital wallet UIs.
Example Code:
```typescript
import { OloPayEvents, DigitalWalletReadyEvent } from '@olo/pay-react-native';
let subscription = OloPayEvents.addListener(
DigitalWalletReadyEvent,
(event: DigitalWalletStatus) => {
// Handle event...
}
);
// Don't forget to unsubscribe when you no longer need to
// know if digital wallets are in a ready state
subscription.remove();
```
[[Back to Top]](#table-of-contents)
## Components
Components are used to display credit card input fields in an app. Credit card details are not accessible by the developer, helping reduce the effort needed to maintain PCI compliance. Details about each component can be found below.
---
### PaymentCardDetailsView
The `PaymentCardDetailsView` component displays all credit card input details in a single input field and is the most compressed way to display a credit card input view. It is composed of a root `<View>` component with two direct children, the credit card input view and a `<Text>` view for displaying error messages. Each piece of the component can be individually styled via `componentStyles`, `cardStyles`, and `errorStyles` _(See [PaymentCardDetailsViewProps](#paymentcarddetailsviewprops))_
#### PaymentCardDetailsViewProps
`PaymentCardDetailsViewProps` provides customization for the card component.
| Property | Description |
| --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| `componentStyles` | Options for styling the root `<View>` component |
| `errorStyles` | Options for styling the error `<Text>` component. _Default style is `{ minHeight: 20 }`_ |
| `cardStyles` | Options for styling credit card input portion of the component. _(See [PaymentCardDetailsViewStyles](#paymentcarddetailsviewstyles))_ |
| `viewProps` | React Native view properties for the root `<View>` component |
| `customErrorMessages` | Options for defining custom error messages in place of defaults _(See [CustomErrorMessages](#customerrormessages))_ |
| `postalCodeEnabled` | Whether or not the postal code should be displayed |
| `disabled` | Whether or not the component is disabled and cannot receive touch and input events |
| `displayErrorMessages` | Whether or not the component should display error messages. Set to `false` if you have a custom mechanism for displaying error messages |
| `placeholders` | Options for specifying placeholder text. _(See [PaymentCardDetailsPlaceholders](#paymentcarddetailsplaceholders))_ |
| `onCardChange(card: CardDetails)` | Card change event handler. Called when input events occur. _(See [CardDetails](#carddetails))_ |
| `onFocus()` | Focus event handler. Called when the component receives input focus |
| `onBlur()` | Blur event handler. Called when the component loses input focus |
| `onFocusField(field: CardField)` | Focus field event handler. Called each time focus moves to a new card input field within the component. _(See [CardField](#cardfield))_ |
<code>{
componentStyles?: StyleProp\<ViewStyle>;
errorStyles?: StyleProp\<TextStyle>;
cardStyles?: [PaymentCardDetailsViewStyles](#paymentcarddetailsviewstyles);
viewProps?: ViewProps;
postalCodeEnabled?: boolean;
disabled?: boolean;
displayErrorMessages?: boolean;
placeholders?: [PaymentCardDetailsPlaceholders](#paymentcarddetailsplaceholders);
onCardChange?(card: [CardDetails](#carddetails)): void;
onFocus?(): void;
onBlur?(): void;
onFocusField?(field: [CardField](#cardfield)): void;
customErrorMessages?: [CustomErrorMessages](#customerrormessages);
}</code>
> **_Important_:** Card field text and error message text have separate styling mechanisms. If the default error colors are changed, it is important to change both of them. An example is provided below:
>
> ```typescript
> <PaymentCardDetailsView
> cardStyles={{ errorTextColor: "#00ff00" }}
> errorStyles={{ color: "#00ff00" }}
> />
> ```
#### PaymentCardDetailsViewMethods
`PaymentCardDetailsViewMethods` defines the native methods that can be called on the `PaymentCardDetailsView` component. These methods can be accessed by passing a `ref` prop of this type into the component, and then calling them on the `ref`. See the `PaymentCardDetailsView` [example](#paymentcarddetailsview-example) code below for details.
**focus()**
```typescript
focus(field?: CardField) => Promise<void>
```
Puts focus on the `PaymentCardDetailsView` component and displays the keyboard. If a [CardField](#cardfield) is passed in, focus will attempt to be given to that field. If no field is passed in, it defaults to `CardField.number`.
If the promise is rejected, the `code` property on the returned error will be [PromiseRejectionCode.viewNotFound](#promiserejectioncode)
**blur()**
```typescript
blur() => Promise<void>
```
Clears focus on the `PaymentCardDetailsView` component and hides the keyboard. If the promise is rejected, the `code` property on the returned error will be [PromiseRejectionCode.viewNotFound](#promiserejectioncode)
**clear()**
```typescript
clear() => Promise<void>
```
Clears all card details entered in the `PaymentCardDetailsView` component. If the promise is rejected, the `code` property on the returned error will be [PromiseRejectionCode.viewNotFound](#promiserejectioncode)
**createPaymentMethod()**
```typescript
createPaymentMethod() => Promise<PaymentMethod>
```
Attempts to create a payment method based on the entered card details. If successful, returns a [PaymentMethod](#paymentmethod) instance.
If the promise is rejected, possible values of the `code` property on the returned error will be one of:
- [PromiseRejectionCode.viewNotFound](#promiserejectioncode)
- [PromiseRejectionCode.invalidNumber](#promiserejectioncode)
- [PromiseRejectionCode.invalidExpiration](#promiserejectioncode)
- [PromiseRejectionCode.invalidCvv](#promiserejectioncode)
- [PromiseRejectionCode.invalidPostalCode](#promiserejectioncode)
- [PromiseRejectionCode.expiredCard](#promiserejectioncode)
- [PromiseRejectionCode.cardDeclined](#promiserejectioncode)
- [PromiseRejectionCode.unknownCardError](#promiserejectioncode)
- [PromiseRejectionCode.processingError](#promiserejectioncode)
- [PromiseRejectionCode.connectionError](#promiserejectioncode)
- [PromiseRejectionCode.invalidRequest](#promiserejectioncode)
- [PromiseRejectionCode.apiError](#promiserejectioncode)
- [PromiseRejectionCode.cancellationError](#promiserejectioncode)
- [PromiseRejectionCode.authenticationError](#promiserejectioncode)
- [PromiseRejectionCode.generalError](#promiserejectioncode)
#### PaymentCardDetailsView Example
```typescript
import {
PaymentCardDetailsView,
PaymentCardDetailsViewMethods,
} from '@olo/pay-react-native';
import { View, Button } from 'react-native';
import { useRef } from 'react';
export default function MyComponent() {
const cardRef = useRef<PaymentCardDetailsViewMethods>(null);
const createPaymentMethod = async () => {
try {
if (!cardRef.current) {
return;
}
let paymentMethod = await cardRef.current.createPaymentMethod();
// Use the payment method to submit a basket using Olo's ordering API
} catch (error) {
// Handle the promise rejection
}
};
// Styling omitted for sake of example simplicity
return (
<View>
<PaymentCardDetailsView displayErrorMessages={true} ref={cardRef} />
<Button title="Submit Payment" onPress={createPaymentMethod} />
</View>
);
}
```
### PaymentCardDetailsForm
The `PaymentCardDetailsForm` component displays all credit card input details in a multi-line form and is the most visible way to display a credit card input view. It is composed of a root `<View>` component with a single nested child, the credit card input form. Each piece of the component can be individually styled via `componentStyles` and `cardStyles` _(See [PaymentCardDetailsFormProps](#paymentcarddetailsformprops))_
#### PaymentCardDetailsFormProps
`PaymentCardDetailsFormProps` provides additional properties defined in the following table
| Property | Description |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------- |
| `componentStyles` | Options for styling the root `<View>` |
| `cardStyles` | Options for styling credit card input portion of the component. _(See [PaymentCardDetailsFormStyles](#paymentcarddetailsformstyles))_ |
| `disabled` | Whether or not the component is disabled and cannot receive touch and input events |
| `onFormComplete()` | Card form complete event handler. Called when form complete events occur. _(See [CardValidationStatus](#cardvalidationstatus))_ |
| `viewProps` | React Native view properties for the root `<View>` component |
| `placeholders` | Options for specifying placeholder text. _(See [PaymentCardDetailsPlaceholders](#paymentcarddetailsplaceholders))_ |
<code>{
cardStyles?: [PaymentCardDetailsFormStyles](#paymentcarddetailsformstyles);
componentStyles?: StyleProp\<ViewStyle>;
disabled?: boolean;
onFormComplete?(cardValidationStatus: [CardValidationStatus](#cardvalidationstatus)): void;
viewProps?: ViewProps;
placeholders?: [PaymentCardDetailsPlaceholders](#paymentcarddetailsplaceholders);
}</code>
#### PaymentCardDetailsFormMethods
`PaymentCardDetailsFormMethods` defines the native methods that can be called on the `PaymentCardDetailsForm` component. These methods can be accessed by passing a `ref` prop of this type into the component, and then calling them on the `ref`. See the `PaymentCardDetailsForm` [example](#paymentcarddetailsform-example) code below for details.
**focus()**
```typescript
focus(field?: CardField) => Promise<void>
```
Puts focus on the `PaymentCardDetailsForm` component and displays the keyboard. If a [CardField](#cardfield) is passed in, focus will attempt to be given to that field. If no field is passed in, it defaults to `CardField.number`.
If the promise is rejected, the `code` property on the returned error will be [PromiseRejectionCode.viewNotFound](#promiserejectioncode)
**blur()**
```typescript
blur() => Promise<void>
```
Clears focus on the `PaymentCardDetailsForm` component and hides the keyboard. If the promise is rejected, the `code` property on the returned error will be [PromiseRejectionCode.viewNotFound](#promiserejectioncode)
**clear()** _(Android Only)_
```typescript
clear() => Promise<void>
```
Clears all card details entered in the `PaymentCardDetailsForm` component. If the promise is rejected, the `code` property on the returned error will be [PromiseRejectionCode.viewNotFound](#promiserejectioncode)
**createPaymentMethod()**
```typescript
createPaymentMethod() => Promise<PaymentMethod>
```
Attempts to create a payment method based on the entered card details. If successful, returns a [PaymentMethod](#paymentmethod) instance.
If the promise is rejected, possible values of the `code` property on the returned error will be one of:
- [PromiseRejectionCode.viewNotFound](#promiserejectioncode)
- [PromiseRejectionCode.isValid](#promiserejectioncode)
- [PromiseRejectionCode.invalidNumber](#promiserejectioncode)
- [PromiseRejectionCode.invalidExpMonth](#promiserejectioncode)
- [PromiseRejectionCode.invalidExpYear](#promiserejectioncode)
- [PromiseRejectionCode.invalidCvv](#promiserejectioncode)
- [PromiseRejectionCode.invalidPostalCode](#promiserejectioncode)
- [PromiseRejectionCode.expiredCard](#promiserejectioncode)
- [PromiseRejectionCode.cardDeclined](#promiserejectioncode)
- [PromiseRejectionCode.unknownCardError](#promiserejectioncode)
- [PromiseRejectionCode.processingError](#promiserejectioncode)
- [PromiseRejectionCode.connectionError](#promiserejectioncode)
- [PromiseRejectionCode.invalidRequestError](#promiserejectioncode)
- [PromiseRejectionCode.apiError](#promiserejectioncode)
- [PromiseRejectionCode.cancellationError](#promiserejectioncode)
- [PromiseRejectionCode.authenticationError](#promiserejectioncode)
- [PromiseRejectionCode.invalidCardDetails](#promiserejectioncode)
- [PromiseRejectionCode.generalError](#promiserejectioncode)
#### PaymentCardDetailsForm Example
```typescript
import { PaymentCardDetailsForm, PaymentCardDetailsFormMethods } from "@olo/pay-react-native";
import { View, Button } from "react-native";
import { useRef } from "react";
export default function MyComponent() {
const cardRef = useRef<PaymentCardDetailsFormMethods>(null);
const createPaymentMethod = async() => {
try {
if (!cardRef.current) {
return;
}
let paymentMethod = await cardRef.current.createPaymentMethod();
// Use the payment method to submit a basket using Olo's ordering API
} catch (error) {
// Handle the promise rejection
}
};
// Styling omitted for sake of example simplicity
return (
<View>
<PaymentCardDetailsForm
ref={cardRef} />
<Button
title="Submit Payment"
onPress={createPaymentMethod} />
</View>
);
};
```
### PaymentCardCvvView
The `PaymentCardCvvView` component displays a single input for a credit card's Card Verification Value (CVV). This is useful to reverify a credit card that has previously been saved with Olo. It is composed of a root `<View>` component with two nested children, the CVV code input and a `<Text>` component for displaying error messages. Each piece of the component can be individually styled via `componentStyles` and `cvvStyles` _(See [PaymentCardCvvViewProps](#paymentcardcvvviewprops))_
#### PaymentCardCvvViewProps
| Property | Description |
| ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| `componentStyles` | Options for styling the root `<View>` component |
| `customErrorMessages` | Option for defining custom error messages in place of defaults _(See [CustomFieldError](#customfielderror))_ |
| `cvvStyles` | Options for styling security code input portion of the component. _(See [PaymentCardCvvViewStyles](#paymentcardcvvviewstyles))_ |
| `displayErrorMessages` | Whether or not the component should display error messages. Set to `false` if you have a custom mechanism for displaying error messages |
| `errorStyles` | Options for styling the error `<Text>` component. _Default style is `{ minHeight: 20 }`_ |
| `disabled` | Whether or not the component is disabled and cannot receive touch and input events |
| `onBlur(cvvDetails: CvvDetails)` | Blur event handler. Called when the component loses input focus _(See [CvvDetails](#cvvdetails))_ |
| `onCvvChange(cvvDetails: CvvDetails)` | Card change event handler. Called when input events occur. _(See [CvvDetails](#cvvdetails))_ |
| `onFocus(cvvDetails: CvvDetails)` | Focus event handler. Called when the component receives input focus _(See [CvvDetails](#cvvdetails))_ |
| `placeholder` | Option for specifying placeholder text. _(See [PaymentCardCvvPlaceholder](#paymentcardcvvplaceholder))_ |
| `viewProps` | React Native view properties for the root `<View>` component |
<code>{
componentStyles?: StyleProp\<ViewStyle>;
customErrorMessages?: [CustomFieldError](#customfielderror);
cvvStyles?: StyleProp\<ViewStyle>;
displayErrorMessages?: boolean;
errorStyles?: StyleProp\<ViewStyle>;
disabled?: boolean:
onBlur(details: [CvvDetails](#cvvdetails))?: void;
onCvvChange(details: [CvvDetails](#cvvdetails))?: void;
onFocus(details: [CvvDetails](#cvvdetails))?: void;
placeholder?: string;
viewProps?: ViewProps;
}
</code>
> **_Important_:** CVV field text and error message text have separate styling mechanisms. If the default error colors are changed, it is important to change both of them. An example is provided below:
>
> ```typescript
> <PaymentCardCvvView
> cvvStyles={{ errorTextColor: "#00ff00" }}
> errorStyles={{ color: "#00ff00" }}
> />
> ```
#### PaymentCardCvvViewMethods
`PaymentCardCvvViewMethods` defines the native methods that can be called on the `PaymentCardCvvView` component. These methods can be accessed by adding a `ref` prop of this type
into the component, and then calling them on the `ref`. See the `PaymentCardCvvView` [example](#paymentcardcvvview-example) code below for details.
**focus()**
```typescript
focus() => Promise<void>
```
Puts focus on the `PaymentCardCvvView` component and displays the keyboard. If the promise is rejected, the `code` property on the returned error will be [PromiseRejectionCode.viewNotFound](#promiserejectioncode)
**blur()**
```typescript
blur() => Promise<void>
```
Clears focus on the `PaymentCardCvvView` component and hides the keyboard. If the promise is rejected, the `code` property on the returned error will be [PromiseRejectionCode.viewNotFound](#promiserejectioncode)
**clear()**
```typescript
clear() => Promise<void>
```
Clears all security code details entered in the `PaymentCardCvvView` component. If the promise is rejected, the `code` property on the returned error will be [PromiseRejectionCode.viewNotFound](#promiserejectioncode)
**createCvvUpdateToken()**
```typescript
createCvvUpdateToken() => Promise<CvvUpdateToken>
```
Attempts to create a CVV update token based on the entered security code details. If successful, returns a [CvvUpdateToken](#cvvupdatetoken) instance.
If the promise is rejected, possible values of the `code` property on the returned error will be one of:
- [PromiseRejectionCode.viewNotFound](#promiserejectioncode)
- [PromiseRejectionCode.invalidCvv](#promiserejectioncode)
- [PromiseRejectionCode.processingError](#promiserejectioncode)
- [PromiseRejectionCode.connectionError](#promiserejectioncode)
- [PromiseRejectionCode.invalidRequest](#promiserejectioncode)
- [PromiseRejectionCode.apiError](#promiserejectioncode)
- [PromiseRejectionCode.cancellationError](#promiserejectioncode)
- [PromiseRejectionCode.authenticationError](#promiserejectioncode)
- [PromiseRejectionCode.generalError](#promiserejectioncode)
#### PaymentCardCvvView Example
```typescript
import {
PaymentCardCvvView,
PaymentCardCvvViewMethods,
} from '@olo/pay-react-native';
import { View, Button } from 'react-native';
import { useRef } from 'react';
export default function MyComponent() {
const cvvRef = useRef<PaymentCardCvvViewMethods>(null);
const createCvvUpdateToken = async () => {
try {
if (!cvvRef.current) {
return;
}
let cvvUpdateToken = await cvvRef.current.createCvvUpdateToken();
// Use the CVV update token for revalidating a stored credit card
} catch (error) {
// Handle the promise rejection
}
};
// Styling omitted for sake of example simplicity
return (
<View>
<PaymentCardCvvView displayErrorMessages={true} ref={cvvRef} />
<Button title="Submit CVV" onPress={createCvvUpdateToken} />
</View>
);
}
```
### DigitalWalletButton
A button that renders a native Apple Pay button on iOS and a native Google Pay button on Android.
#### DigitalWalletButtonProps
| Property | Description |
| ----------------- | ------------------------------------------------------------------------------------------------------------------ |
| `applePayConfig` | Options for customizing the button for Apple Pay on iOS (See [ApplePayButtonConfig](#applepaybuttonconfig)) |
| `googlePayConfig` | Options for customizing the button for Google Pay on Android (See [GooglePayButtonConfig](#googlepaybuttonconfig)) |
| `styles` | Options for styling the button. Default styles provide a minimum height of `40` on Android and `30` on iOS |
| `disabled` | Whether or not the component is disabled and cannot receive touch events |
| `onPress()` | Event handler for button presses |
<code>{
applePayConfig?: [ApplePayButtonConfig](#applepaybuttonconfig);
googlePayConfig?: [GooglePayButtonConfig](#googlepaybuttonconfig);
disabled?: boolean;
onPress(): void;
styles?: StyleProp\<ViewStyle\>;
}
</code>
#### DigitalWalletButton Example
```typescript
import {
ApplePayButtonStyle,
ApplePayButtonType,
DigitalWalletButton,
GooglePayButtonTheme,
GooglePayButtonType,
OloPaySDK
} from '@olo/pay-react-native';
export default function MyComponent() {
const createDigitalWalletPaymentMethod = async () => {
try {
let result = await OloPaySDK.createDigitalWalletPaymentMethod();
// Use result.paymentMethod method to submit a basket using Olo's ordering API
// or result.error to handle additional error scenarios
} catch (error) {
// Handle the promise rejection
}
};
// Styling omitted for sake of example simplicity
return (
<DigitalWalletButton
onPress={createDigitalWalletPaymentMethod}
googlePayConfig={{
theme: GooglePayButtonTheme.dark,
type: GooglePayButtonType.checkout,
cornerRadius: 8,
}}
applePayConfig={{
style: ApplePayButtonStyle.black,
type: ApplePayButtonType.checkout,
cornerRadius: 8,
}}
/>
);
}
```
[[Back to Top]](#table-of-contents)
## OloPaySDK Module
Native SDK methods can be called on the imported `OloPaySDK` object. This module is responsible for initializing the Olo Pay SDK and processing digital wallet payments.
```typescript
import { OloPaySDK } from '@olo/pay-react-native';
```
<docgen-index>
* [`initialize(...)`](#initialize)
* [`updateDigitalWalletConfig(...)`](#updatedigitalwalletconfig)
* [`createDigitalWalletPaymentMethod(...)`](#createdigitalwalletpaymentmethod)
* [`isInitialized()`](#isinitialized)
* [`isDigitalWalletInitialized()`](#isdigitalwalletinitialized)
* [`isDigitalWalletReady()`](#isdigitalwalletready)
* [Type Aliases](#type-aliases)
* [Enums](#enums)
</docgen-index>
## Methods
<docgen-api>
<!--Update the source file JSDoc comments and rerun docgen to update the docs below-->
### initialize(...)
```typescript
initialize(productionEnvironment: boolean, digitalWalletConfig?: DigitalWalletConfig | undefined) => Promise<void>
```
Initialize the Olo Pay SDK and, optionally, configure and initialize digital wallets. The SDK must be initialized prior to calling other methods. Calling this method **will** ensure that the Olo Pay SDK is initialized.
If a [DigitalWalletConfig](#digitalwalletconfig) is provided, when digital wallets become ready, a [DigitalWalletReadyEvent](#digitalwalletreadyevent) will be emitted. If digital wallets are not configured
and initialized here, this can be done later by calling [updateDigitalWalletConfig](#updatedigitalwalletconfig).
**Important:** The Olo Pay SDK is guaranteed to be initialized even if the promise is rejected. Promise rejections will only occur due to an error while initializing digital wallets, which happens after successful SDK initialization.
If the promise is rejected, the `code` property of the returned error object will be one of:
- [PromiseRejectionCode.missingParameter](#promiserejectioncode)
- [PromiseRejectionCode.invalidParameter](#promiserejectioncode)
- [PromiseRejectionCode.googlePayInvalidSetup](#promiserejectioncode) **_(Android only)_**
- [PromiseRejectionCode.unexpectedError](#promiserejectioncode) **_(Android only)_**
| Param | Type | Description |
| --------------------------- | ------------------------------------------------------------------- | -------------------------------------------------------------------------- |
| **`productionEnvironment`** | <code>boolean</code> | `true` to use the production environment, `false` for the test environment |
| **`digitalWalletConfig`** | <code><a href="#digitalwalletconfig">DigitalWalletConfig</a></code> | Initialization options for digital wallets |
--------------------
### updateDigitalWalletConfig(...)
```typescript
updateDigitalWalletConfig(digitalWalletConfig: DigitalWalletConfig) => Promise<void>
```
Update the configuration settings for digital wallets.
This can be used to change configuration parameters for digital wallets. Calling this method will
immediately invalidate digital wallet readiness and will cause a [DigitalWalletReadyEvent](#digitalwalletreadyevent)
to be emitted with a value of `false`. Once the new configuration is ready to be used,
the [DigitalWalletReadyEvent](#digitalwalletreadyevent) will be triggered again with a value of `true`.
**Note:** This method can also be used to initialize digital wallets if they were not initialized as part of SDK initialization (see [initialize](#initialize)).
If the promise is rejected, the `code` property of the returned error object will be one of:
- [PromiseRejectionCode.missingParameter](#promiserejectioncode)
- [PromiseRejectionCode.invalidParameter](#promiserejectioncode)
- [PromiseRejectionCode.sdkUninitialized](#promiserejectioncode)
- [PromiseRejectionCode.googlePayInvalidSetup](#promiserejectioncode) **_(Android only)_**
- [PromiseRejectionCode.unexpectedError](#promiserejectioncode) **_(Android only)_**
| Param | Type | Description |
| ------------------------- | ------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| **`digitalWalletConfig`** | <code><a href="#digitalwalletconfig">DigitalWalletConfig</a></code> | The new configuration settings for digital wallets. See [DigitalWalletConfig](#digitalwalletconfig) for more details. |
--------------------
### createDigitalWalletPaymentMethod(...)
```typescript
createDigitalWalletPaymentMethod(options: DigitalWalletPaymentRequestOptions) => Promise<DigitalWalletPaymentMethodResult>
```
Launch the digital wallet flow and generate a payment method to be used with Olo's Ordering API.
If the promise is rejected, the `code` property of the returned error object will be one of:
- [PromiseRejectionCode.sdkUninitialized](#promiserejectioncode)
- [PromiseRejectionCode.digitalWalletUninitialized](#promiserejectioncode)
- [PromiseRejectionCode.digitalWalletNotReady](#promiserejectioncode)
- [PromiseRejectionCode.invalidParameter](#promiserejectioncode)
- [PromiseRejectionCode.missingParameter](#promiserejectioncode)
- [PromiseRejectionCode.emptyCompanyLabel](#promiserejectioncode)
- [PromiseRejectionCode.invalidCountyCode](#promiserejectioncode)
- [PromiseRejectionCode.lineItemsTotalMismatch](#promiserejectioncode)
- [PromiseRejectionCode.applePayEmptyMerchantId](#promiserejectioncode) **_(iOS only)_**
- [PromiseRejectionCode.applePayUnsupported](#promiserejectioncode) **_(iOS only)_**
- [PromiseRejectionCode.applePayError](#promiserejectioncode) **_(iOS only)_**
- [PromiseRejectionCode.applePayTimeout](#promiserejectioncode) **_(iOS only)_**
- [PromiseRejectionCode.googlePayNetworkError](#promiserejectioncode) **_(Android only)_**
- [PromiseRejectionCode.googlePayDeveloperError](#promiserejectioncode) **_(Android only)_**
- [PromiseRejectionCode.googlePayInternalError](#promiserejectioncode) **_(Android only)_**
- [PromiseRejectionCode.unexpectedError](#promiserejectioncode) **_(Android only)_**
- [PromiseRejectionCode.generalError](#promiserejectioncode)
```typescript
try {
const { paymentMethod } = await createDigitalWalletPaymentMethod({ amount: 5.00 });
if (paymentMethod === undefined) {
// User canceled the digital wallet flow
} else {
// Send paymentMethod to Olo's Ordering API
}
} catch (error) {
// Handle error
}
```
| Param | Type | Description |
| ------------- | ------------------------------------------------------------------------------------------------- | ------------------------------------------------ |
| **`options`** | <code><a href="#digitalwalletpaymentrequestoptions">DigitalWalletPaymentRequestOptions</a></code> | Options for processing a digital wallet payment. |
**Returns:** <code>Promise<<a href="#digitalwalletpaymentmethodresult">DigitalWalletPaymentMethodResult</a>></code>
--------------------
### isInitialized()
```typescript
isInitialized() => Promise<InitializationStatus>
```
Check if the Olo Pay SDK has been initialized
**Returns:** <code>Promise<<a href="#initializationstatus">InitializationStatus</a>></code>
--------------------
### isDigitalWalletInitialized()
```typescript
isDigitalWalletInitialized() => Promise<InitializationStatus>
```
Check if digital wallets have been initialized. On iOS, digital wallets are initialized when the SDK is initialized, so this method
will behave the same as `isInitialized()`. On Android, a separate call to `initializeGooglePay()` is required to initialize digital wallets.
**Returns:** <code>Promise<<a href="#initializationstatus">InitializationStatus</a>></code>
--------------------
### isDigitalWalletReady()
```typescript
isDigitalWalletReady() => Promise<DigitalWalletStatus>
```
Check if digital wallets are ready to be used. Events are emitted whenever the digital wallet status
changes, so listenting to that event can be used instead of calling this method, if desired.
**Returns:** <code>Promise<<a href="#digitalwalletstatus">DigitalWalletStatus</a>></code>
--------------------
### Type Aliases
#### DigitalWalletConfig
Options for intializing digital wallets
| Property | Description | Default |
| -------- | ----------- | ------- |
| `countryCode` | A two character country code for the vendor that will be processing the payment | 'US' |
| `currencyCode` | Currency code to be used for transactions | <a href="#currencycode">`CurrencyCode</a>.usd` |
| `companyLabel` | The company display name | - |
| `emailRequired` | Whether an email will be collected and returned when processing transactions | `false` |
| `fullNameRequired` | Whether a full name will be collected and returned when processing transactions | `false` |
| `fullBillingAddressRequired` | Whether a full billing address will be collected and returned when processing transactions | `false` |
| `phoneNumberRequired` | Whether a phone number will be collected and returned when processing transactions | `false` |
| `initializeApplePay` | Whether Apple Pay should be initialized. | - |
| `initializeGooglePay` | Whether Google Pay should be initialized. | - |
| `applePayConfig` | Configuration options for initializing Apple Pay. Required if `initializeApplePay` is `true` | - |
| `googlePayConfig` | Configuration options for initializing Google Pay. Required if `initializeGooglePay` is `true` | - |
**Note:** If Apple Pay or Google Pay were previously initialized and the respective initialize property (`initializeApplePay` or `initializeGooglePay`) is set to `false`, this will not uninitialize digital wallets and will result in a no-op.
<code>{ companyLabel: string; countryCode?: string; currencyCode?: <a href="#currencycode">CurrencyCode</a>; emailRequired?: boolean; phoneNumberRequired?: boolean; fullNameRequired?: boolean; fullBillingAddressRequired?: boolean; initializeApplePay: boolean; initializeGooglePay: boolean; applePayConfig?: <a href="#applepayconfig">ApplePayConfig</a>; googlePayConfig?: <a href="#googlepayconfig">GooglePayConfig</a>; }</code>
#### CurrencyCode
Type alias representing currency codes supported by Olo Pay.
<code>'USD' | 'CAD'</code>
#### ApplePayConfig
Options for initializing Apple Pay
| Property | Description | Default |
| -------- | ----------- | ------- |
| `fullPhoneticNameRequired` | Whether a full phonetic name will be collected and returned when processing transactions | `false` |
| `merchantId` | The merchant id registered with Apple for Apple Pay | - |
<code>{ fullPhoneticNameRequired?: boolean; merchantId: string; }</code>
#### GooglePayConfig
Options for intializing Google Pay
| Property | Description | Default |
| -------- | ----------- | ------- |
| `productionEnvironment` | Whether Google Pay will use the production environment | `true` |
| `existingPaymentMethodRequired` | Whether an existing saved payment method is required for Google Pay to be considered ready | `false` |
| `currencyMultiplier` | Multiplier to convert the amount to the currency's smallest unit (e.g. $2.34 * 100 = 234 cents) | `100` |
<code>{ productionEnvironment?: boolean; existingPaymentMethodRequired?: boolean; currencyMultiplier?: number; }</code>
#### DigitalWalletPaymentMethodResult
Type alias representing a digital wallet payment method result.
| Property | Description |
| -------- | ----------- |
| `paymentMethod` | The payment method generated by the digital wallet flow, or `undefined` if the user canceled the flow |
<code>{ paymentMethod?: <a href="#paymentmethod">PaymentMethod</a>; }</code>
#### PaymentMethod
Payment method used for submitting payments to Olo's Ordering API
| Property | Description |
| -------- | ----------- |
| `id` | The payment method id. This should be set to the `token` field when submitting a basket |
| `last4` | The last four digits of the card |
| `cardType` | The issuer of the card |
| `expMonth` | Two-digit number representing the card's expiration month |
| `expYear` | Four-digit number representing the card's expiration year |
| `postalCode` | Zip or postal code. Will always have the same value as `billingAddress.postalCode` |
| `countryCode` | Two character country code. Will always have the same value as `billingAddress.countryCode` |
| `isDigitalWallet` | `true` if this payment method was created by digital wallets (e.g. Apple Pay or Google Pay), `false` otherwise |
| `productionEnvironment` | `true` if this payment method was created in the production environment, `false` otherwise |
| `email` | The email address associated with the transaction, or an empty string if unavailable. Only provided for digital wallet payment methods (see `isDigitalWallet`) |
| `digitalWalletCardDescription` | The description of the card, as provided by Apple or Google. Only provided for digital wallet payment methods (see `isDigitalWallet`) |
| `billingAddress` | The billing address associated with the transaction. The country code and postal code fields will always have a non-empty value. Other fields will only have non-empty values for digital wallet payment methods (see `isDigitalWallet`) |
| `fullName` | The full name associated with the transaction. Will only have a non-empty value for digital wallet payment methods (see `isDigitalWallet`) |
| `fullPhoneticName` | The full phonetic name associated with the transaction. Will only have a non-empty value for digital wallet payment methods (see `isDigitalWallet`) **_(iOS only)_** |
<code>{ id: string; last4: string; cardType: <a href="#cardtype">CardType</a>; expMonth: number; expYear: number; postalCode: string; countryCode: string; isDigitalWallet: boolean; productionEnvironment: boolean; email: string; digitalWalletCardDescription: string; billingAddress: <a href="#address">Address</a>; fullName: string; fullPhoneticName: string; phoneNumber: string; }</code>
#### Address
Represents an address. Currently only used for digital wallets, if billing address details are requested to be returned in the
generated digital wallet payment method.
| Property | Description |
| -------- | ----------- |
| `address1` | The first line of the address |
| `address2` | The second line of the address, or an empty string |
| `address3` | The third line of the address, or an empty string |
| `postalCode` | The postal or zip code |
| `countryCode` | The two digit ISO country code |
| `administrativeArea` | A country subdivision, such as a state or province |
<code>{ address1: string; address2: string; address3: string; locality: string; postalCode: string; countryCode: string; administrativeArea: string; }</code>
#### DigitalWalletPaymentRequestOptions
Type alias representing options for a digital wallet payment method request
<code><a href="#googlepaypaymentrequestoptions">GooglePayPaymentRequestOptions</a> | <a href="#applepaypaymentrequestoptions">ApplePayPaymentRequestOptions</a></code>
#### GooglePayPaymentRequestOptions
Options for requesting a payment method via Google Pay
| Property | Description | Default |
| -------- | ----------- | ------- |
| `amount` | The amount to be charged | - |
| `checkoutStatus` | The checkout status to be used for the transaction | `FinalImmediatePurchase` |
| `totalPriceLabel` | A custom value to override the default total price label in the Google Pay sheet | - |
| `lineItems` | A list of line items to be displayed in the digital wallet payment sheet | - |
| `validateLineItems` | Whether or not to validate the line items. If `true`, [createDigitalWalletPaymentMethod](#createdigitalwalletpaymentmethod) will throw an exception if the sum of the line items does not equal the total amount passed in. If no line items are provided, this parameter is ignored. | `true` |
<code>{ amount: number; checkoutStatus?: <a href="#googlepaycheckoutstatus">GooglePayCheckoutStatus</a>; totalPriceLabel?: string; lineItems?: LineItem[]; validateLineItems?: boolean; }</code>
#### LineItem
Represents a line item in a digital wallet transaction
| Property | Description |
| -------- | ----------- |
| `label` | The label of the line item |
| `amount` | The amount of the line item |
| `type` | Enum representing the type of a line item in a digital wallet transaction |
| `status` | Enum representing the status of a line item. If not provided, default value is <a href="#lineitemstatus">`Li