Skip to content

Commit

Permalink
Merge pull request #76 from degica/task/MOB-61
Browse files Browse the repository at this point in the history
3d secure integration
  • Loading branch information
tharindu-rhino authored Sep 10, 2024
2 parents 0fbe1c7 + d3ce8fb commit 5335bf8
Show file tree
Hide file tree
Showing 25 changed files with 730 additions and 436 deletions.
10 changes: 6 additions & 4 deletions example/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, {useEffect, useState} from "react";
import {SafeAreaView, StyleSheet} from "react-native";
import {KomojuSDK, LanguageTypes} from "@komoju/komoju-react-native";
import React, { useEffect, useState } from "react";
import { SafeAreaView, StyleSheet } from "react-native";
import { KomojuSDK, LanguageTypes } from "@komoju/komoju-react-native";

import PaymentScreen from "./components/PaymentScreen";
import LanguageSelectComponent from "./components/languageSelectComponet";
Expand Down Expand Up @@ -35,7 +35,9 @@ function App(): React.JSX.Element {
<KomojuSDK.KomojuProvider
publishableKey={publishableKey}
// theme={theme}
language={language}>
language={language}
urlScheme="komapp://"
>
<PaymentScreen language={language} setLoading={setLoading} />
</KomojuSDK.KomojuProvider>

Expand Down
29 changes: 12 additions & 17 deletions example/src/components/PaymentScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ import {
Pressable,
Alert,
} from "react-native";
import { KomojuSDK, SessionShowResponseType } from "@komoju/komoju-react-native";
import {
KomojuSDK,
SessionShowResponseType,
} from "@komoju/komoju-react-native";
import createSession from "../services/sessionService";

export enum CurrencyTypes {
Expand Down Expand Up @@ -37,7 +40,7 @@ const PaymentScreen = ({
}

// fetch a session Id to initiate payment
const sessionId = await createSession({amount, currency, language});
const sessionId = await createSession({ amount, currency, language });
setLoading(false);

// invoke createPayment method with sessionId as parameters to open the payment portal
Expand All @@ -62,27 +65,23 @@ const PaymentScreen = ({
<View style={[styles.container]}>
<View style={styles.currencyRow}>
{(Object.keys(CurrencyTypes) as Array<keyof typeof CurrencyTypes>).map(
key => (
(key) => (
<Pressable
key={key}
onPress={() => changeCurrencyType(CurrencyTypes[key])}
style={[
styles.currencyTextContainer,
key === currency && styles.currencySelectedTextContainer,
]}>
<Text
style={[
key === currency && styles.currencySelectedText,
]}>
]}
>
<Text style={[key === currency && styles.currencySelectedText]}>
{key}
</Text>
</Pressable>
),
)
)}
</View>
<Text style={[styles.title]}>
Enter Amount to Pay with Komoju
</Text>
<Text style={[styles.title]}>Enter Amount to Pay with Komoju</Text>
<TextInput
style={[styles.input]}
placeholder="Enter amount"
Expand All @@ -92,11 +91,7 @@ const PaymentScreen = ({
onChangeText={setAmount}
/>
<View style={styles.buttonContainer}>
<Button
title="Checkout"
onPress={handleSessionPay}
color={"#007AFF"}
/>
<Button title="Checkout" onPress={handleSessionPay} color={"#007AFF"} />
</View>
</View>
);
Expand Down
9 changes: 8 additions & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,18 @@ react-i18next

## Usage example

For a complete example, [visit our docs](https://doc.komoju.com/docs/react-native).

```tsx
// App.ts
import { KomojuSDK } from "@komoju/komoju-react-native";

function App() {
return (
<KomojuSDK.KomojuProvider publishableKey={PUBLISHABLE_KEY}>
<KomojuSDK.KomojuProvider
publishableKey={PUBLISHABLE_KEY}
urlScheme="your-url-scheme"
>
<PaymentScreen />
</KomojuSDK.KomojuProvider>
);
Expand Down Expand Up @@ -101,6 +106,7 @@ function App() {
return (
<KomojuSDK.KomojuProvider
publishableKey={publishableKey}
urlScheme="your-url-scheme" // required for 3D Secure and bank redirects
paymentMethods={[PaymentTypes.KONBINI]} // explicitly set the payment method(s) for purchase
language={LanguageTypes.JAPANESE} // explicitly set the language, if not set language will be picked from your session Id
>
Expand All @@ -115,5 +121,6 @@ function App() {
| property | type | description |
| ------------------ | ------------------------ | ------------------------------------------------------------------------------------------------------------- |
| **publishableKey** | `string` | Your publishable key from the KOMOJU [merchant settings page](https://komoju.com/sign_in/) (this is mandtory) |
| **urlScheme** | `string` | Your return url for customers to return to the app after completing browser authentications |
| **paymentMethods** | `Array <PaymentTypes>` | explicitly set the payment method(s) for purchase. (optional) |
| **language** | `string (LanguageTypes)` | explicitly set the language, if not set language will be picked from your session Id (optional) |
11 changes: 0 additions & 11 deletions src/__tests__/CardSection.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,16 +61,5 @@ describe("Card Section Test cases", () => {

// Simulate pressing the Pay button
fireEvent.press(payButton);

// Check if sessionPay was called with the correct arguments
expect(mockState.sessionPay).toHaveBeenCalledWith({
paymentType: PaymentType.CREDIT,
paymentDetails: {
cardholderName: mockState.cardholderName,
cardCVV: mockState.cardCVV,
cardNumber: mockState.cardNumber,
cardExpiredDate: mockState.cardExpiredDate,
},
});
});
});
18 changes: 7 additions & 11 deletions src/components/sections/CardSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ import { StyleSheet, View } from "react-native";
import { Actions, DispatchContext, StateContext } from "../../context/state";

import { formatCurrency } from "../../util/helpers";
import { PaymentType } from "../../util/types";
import { validateCardFormFields } from "../../util/validator";

import { responsiveScale } from "../../theme/scalling";

import CardInputGroup from "../CardInputGroup";
import Input from "../Input";
import SubmitButton from "../SubmitButton";
import useThreeDSecureHandler from "../../hooks/useThreeDSecureHandler";

const initialErrors = {
name: false,
Expand All @@ -29,9 +29,8 @@ const initialErrors = {

const CardSection = (): JSX.Element => {
const [inputErrors, setInputErrors] = useState(initialErrors);

const { threeDSecurePayment } = useThreeDSecureHandler();
const {
sessionPay,
cardholderName,
cardCVV,
cardNumber,
Expand Down Expand Up @@ -59,14 +58,11 @@ const CardSection = (): JSX.Element => {
});

if (isValid) {
sessionPay({
paymentType: PaymentType.CREDIT,
paymentDetails: {
cardholderName,
cardCVV,
cardNumber,
cardExpiredDate,
},
threeDSecurePayment({
cardholderName,
cardCVV,
cardNumber,
cardExpiredDate,
});
}
};
Expand Down
13 changes: 4 additions & 9 deletions src/components/sections/KonbiniSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { responsiveScale } from "../../theme/scalling";
import Input from "../Input";
import Pill from "../Pill";
import SubmitButton from "../SubmitButton";
import useSessionPayHandler from "../../hooks/useSessionPayHandler";

const initialErrors = {
name: false,
Expand All @@ -29,15 +30,9 @@ const initialErrors = {
const KonbiniSection = (): JSX.Element => {
const [inputErrors, setInputErrors] = useState(initialErrors);

const {
sessionPay,
name,
email,
amount,
currency,
paymentMethods,
selectedStore,
} = useContext(StateContext);
const { sessionPay } = useSessionPayHandler();
const { name, email, amount, currency, paymentMethods, selectedStore } =
useContext(StateContext);
const dispatch = useContext(DispatchContext);

const konbiniPaymentMethodData = paymentMethods?.find(
Expand Down
6 changes: 3 additions & 3 deletions src/components/sections/PaidyFormSection.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { useContext, useState } from "react";
import { useState } from "react";

import { StyleSheet, View } from "react-native";

import { StateContext } from "../../context/state";
import useSessionPayHandler from "../../hooks/useSessionPayHandler";

import Input from "../../components/Input";

Expand All @@ -22,7 +22,7 @@ const PaidyFormSection = ({ type }: PaidyFormSectionProps) => {
const [inputValues, setInputValues] = useState({ name: "", phone: "" });
const [inputErrors, setInputErrors] = useState({ name: false, phone: false });

const { sessionPay } = useContext(StateContext);
const { sessionPay } = useSessionPayHandler();

const onPay = () => {
const isValid = validatePaidyFormFields({
Expand Down
117 changes: 58 additions & 59 deletions src/components/sections/SimpleRedirectSection.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { useContext } from "react";

import { StyleSheet, View } from "react-native";

import { StateContext } from "../../context/state";
import useSessionPayHandler from "../../hooks/useSessionPayHandler";

import LightBox from "../../components/LightBox";

Expand All @@ -16,67 +14,68 @@ import KomojuText from "../KomojuText";
import SubmitButton from "../SubmitButton";

type SimpleRedirectSectionProps = {
type: PaymentType;
}
type: PaymentType;
};

const SimpleRedirectSection = ({ type }: SimpleRedirectSectionProps) => {
const { sessionPay } = useContext(StateContext);
const theme = useCurrentTheme();
const styles = getStyles(theme);
const onPay = () => {
sessionPay({ paymentType: type });
};
const { sessionPay } = useSessionPayHandler();

return (
<View style={styles.container}>
<View style={styles.textContent}>
<KomojuText style={styles.title}>{`PAYMENT_VIA_${LangKeys[type]}`}</KomojuText>
<KomojuText style={styles.description}>
{`${LangKeys[type]}_REDIRECT_MESSAGE`}
</KomojuText>
</View>
<View style={styles.lbWrapper}>
<LightBox
content="LIGHT_BOX_CONTENT"
/>
</View>
<View style={styles.btn}>
<SubmitButton onPress={onPay} label={`CONTINUE_TO_${LangKeys[type]}`} />
</View>
</View>
);
const theme = useCurrentTheme();
const styles = getStyles(theme);
const onPay = () => {
sessionPay({ paymentType: type });
};

return (
<View style={styles.container}>
<View style={styles.textContent}>
<KomojuText
style={styles.title}
>{`PAYMENT_VIA_${LangKeys[type]}`}</KomojuText>
<KomojuText style={styles.description}>
{`${LangKeys[type]}_REDIRECT_MESSAGE`}
</KomojuText>
</View>
<View style={styles.lbWrapper}>
<LightBox content="LIGHT_BOX_CONTENT" />
</View>
<View style={styles.btn}>
<SubmitButton onPress={onPay} label={`CONTINUE_TO_${LangKeys[type]}`} />
</View>
</View>
);
};

export default SimpleRedirectSection;

const getStyles = (theme: ThemeSchemeType) => {
return StyleSheet.create({
container: {
flexGrow: 1,
},
textContent: {
marginBottom: responsiveScale(24),
marginTop: responsiveScale(16),
marginHorizontal: responsiveScale(16),
},
title: {
fontSize: resizeFonts(20),
fontWeight: "bold",
color: theme.TEXT_COLOR,
marginBottom: responsiveScale(8),
},
description: {
fontSize: resizeFonts(16),
color: theme.TEXT_COLOR,
},
lbWrapper: {
minHeight: responsiveScale(80),
marginHorizontal: responsiveScale(16),
marginBottom: responsiveScale(24),
},
btn: {
height: responsiveScale(60),
marginBottom: responsiveScale(24),
},
});
}
return StyleSheet.create({
container: {
flexGrow: 1,
},
textContent: {
marginBottom: responsiveScale(24),
marginTop: responsiveScale(16),
marginHorizontal: responsiveScale(16),
},
title: {
fontSize: resizeFonts(20),
fontWeight: "bold",
color: theme.TEXT_COLOR,
marginBottom: responsiveScale(8),
},
description: {
fontSize: resizeFonts(16),
color: theme.TEXT_COLOR,
},
lbWrapper: {
minHeight: responsiveScale(80),
marginHorizontal: responsiveScale(16),
marginBottom: responsiveScale(24),
},
btn: {
height: responsiveScale(60),
marginBottom: responsiveScale(24),
},
});
};
4 changes: 3 additions & 1 deletion src/components/sections/SingleInputFormSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { PaymentType } from "../../util/types";
import { responsiveScale } from "../../theme/scalling";

import SubmitButton from "../SubmitButton";
import useSessionPayHandler from "../../hooks/useSessionPayHandler";

type SingleInputFormSectionProps = {
type: PaymentType;
Expand All @@ -21,7 +22,8 @@ type SingleInputFormSectionProps = {
const SingleInputFormSection = ({ type }: SingleInputFormSectionProps) => {
const [inputText, setInputText] = useState("");
const [inputError, setInputError] = useState(false);
const { sessionPay, amount, currency } = useContext(StateContext);
const { amount, currency } = useContext(StateContext);
const { sessionPay } = useSessionPayHandler();

const onPay = () => {
if (!inputText) {
Expand Down
Loading

0 comments on commit 5335bf8

Please sign in to comment.