Skip to content

Commit

Permalink
Merge pull request #104 from mediaopt/feature/36077-google-pay
Browse files Browse the repository at this point in the history
Feature/36077 google pay
  • Loading branch information
JonYeb authored May 13, 2024
2 parents 16037c5 + cf05ab1 commit 417cf9a
Show file tree
Hide file tree
Showing 16 changed files with 257 additions and 52 deletions.
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,29 @@ PayPal messages props are based on PayPalMessages props and you can see them on
- **applePayDisplayName**: `string`
Name of your store.


### GooglePay
Have a look at [Googles specification](https://developers.google.com/pay/api/web/reference/request-objects) for a detailed explanation of the options
- **environment**: `string`
"TEST" or "PRODUCTION";
- **allowedCardNetworks**: `string[]`
One or more card networks that you support, also supported by the Google Pay API.
- **allowedCardAuthMethods**: `string`
"PAN_ONLY" (cards on file) and "CRYPTOGRAM_3DS" (Android powered device token)
- **callbackIntents**: `string[]`
Specifies intents for PaymentDataCallback
- **apiVersion**: `number`
Major API version
- **apiVersionMinor**: `number`
Minor API version
- **totalPriceStatus**: `string`
"FINAL" or "ESTIMATED"
- **buttonColor**: `string`
- **buttonType**: `string`
- **buttonRadius**: `number`
- **buttonSizeMode**: `string`
- **verificationMethod**: `string`

### CardFields

- **authenticateThreeDSOrderUrl**: `string`
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "paypal-commercetools-client",
"version": "0.1.31",
"version": "0.1.32",
"private": false,
"type": "module",
"license": "MIT",
Expand Down
10 changes: 6 additions & 4 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ import {
GooglePayOptionsType,
PayUponInvoiceProps,
SmartComponentsProps,
ThreeDSVerification,
} from "./types";
import { GooglePay } from "./components/GooglePay";

const CC_FRONTEND_EXTENSION_VERSION: string = "devmajidabbasi";
const CC_FRONTEND_EXTENSION_VERSION: string = "devjonathanyeboah";
const FRONTASTIC_SESSION: string =
"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJjYXJ0SWQiOiI3NTlhZDdkMS1jZTNhLTRmZmUtYjc1MC1lODFmNWRiMTZiYTMiLCJhY2NvdW50Ijp7ImFjY291bnRJZCI6ImYyMmE0ZmUzLWMyYjgtNDgwMS04MjA4LTQxNGQyMDYyMGUwYiIsImVtYWlsIjoibWFqaWQuYWJiYXNpQG1lZGlhb3B0LmRlIiwic2FsdXRhdGlvbiI6IiIsImZpcnN0TmFtZSI6Ik1hamlkIiwibGFzdE5hbWUiOiJBYmJhc2kiLCJiaXJ0aGRheSI6IjE5ODktMDMtMDVUMDA6MDA6MDAuMDAwWiIsImNvbmZpcm1lZCI6dHJ1ZSwiYWRkcmVzc2VzIjpbeyJhZGRyZXNzSWQiOiJqYlRKWG0zTSIsImZpcnN0TmFtZSI6Ik1hamlkIiwibGFzdE5hbWUiOiJBYmJhc2kiLCJzdHJlZXROYW1lIjoiSG9jaHN0cmFcdTAwZGZlIDM3Iiwic3RyZWV0TnVtYmVyIjoiSG9jaHN0cmFcdTAwZGZlIDM3IiwicG9zdGFsQ29kZSI6IjEzMzU3IiwiY2l0eSI6IkRFIiwiY291bnRyeSI6IkRFIiwicGhvbmUiOiI1OTkzNTc1NjIiLCJpc0RlZmF1bHRCaWxsaW5nQWRkcmVzcyI6ZmFsc2UsImlzRGVmYXVsdFNoaXBwaW5nQWRkcmVzcyI6ZmFsc2V9LHsiYWRkcmVzc0lkIjoia3J6UjdtMFEiLCJmaXJzdE5hbWUiOiJNYWppZCIsImxhc3ROYW1lIjoiQWJiYXNpIiwic3RyZWV0TmFtZSI6IkNvdW50eSBTdC4gTWlhbWkiLCJzdHJlZXROdW1iZXIiOiI0MzIiLCJwb3N0YWxDb2RlIjoiMzMwMTgiLCJjaXR5IjoiVVMiLCJjb3VudHJ5IjoiREUiLCJwaG9uZSI6IjU5OTM1NzU2MiIsImlzRGVmYXVsdEJpbGxpbmdBZGRyZXNzIjp0cnVlLCJpc0RlZmF1bHRTaGlwcGluZ0FkZHJlc3MiOnRydWV9XX0sIndpc2hsaXN0SWQiOiJjZTM4MzVkMC02OWM0LTRlZWUtYTBjZC1hM2I4NjgyYTU2OTUifQ.iixjVD4AkF2io8SJZ-AS8-cVE8v-Xou_2EKV6YaptXE";

"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJjYXJ0SWQiOiJhMGFkZjllNy00YmJlLTRiMzgtYmZjZS1mMTdlMWFiZDM0OTcifQ.dFSz1WocjOFGUkHqjQYdkT1DEebN63vp0MrZzIXXoIM";
function App() {
const [choosenPaymentMethod, setChoosenPaymentMethod] = useState("");

Expand Down Expand Up @@ -70,6 +70,7 @@ function App() {
const params = {
...commonParams,
createOrderUrl: `${ENDPOINT_URL}/payment/createPayPalOrder`,
getOrderUrl: `${ENDPOINT_URL}/payment/getPayPalOrder`,
authorizeOrderUrl: `${ENDPOINT_URL}/payment/authorizePayPalOrder`,
onApproveUrl: `${ENDPOINT_URL}/payment/capturePayPalOrder`,
shippingMethodId: "da416140-39bf-4677-8882-8b6cab23d981",
Expand Down Expand Up @@ -171,8 +172,9 @@ function App() {
options: { ...options, components: "googlepay" },
environment: "TEST" as "TEST",
allowedCardNetworks: ["MASTERCARD", "VISA"],
allowedCardAuthMethods: ["PAN_ONLY", "CRYPTOGRAM_3DS"],
allowedCardAuthMethods: ["PAN_ONLY"],
callbackIntents: ["PAYMENT_AUTHORIZATION"],
verificationMethod: "SCA_ALWAYS" as ThreeDSVerification,
};

const paymentMethods: { [index: string]: React.JSX.Element } = {
Expand Down
26 changes: 25 additions & 1 deletion src/app/usePayment.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import { getClientToken } from "../services/getClientToken";
import { getActionIndex } from "../components/CardFields/constants";
import { useTranslation } from "react-i18next";
import { handleResponseError } from "../messages/errorMessages";
import { getOrder } from "../services/getOrder";

const PaymentInfoInitialObject = {
version: 0,
Expand Down Expand Up @@ -113,6 +114,7 @@ export const PaymentProvider: FC<

createPaymentUrl,
createOrderUrl,
getOrderUrl,
authorizeOrderUrl,
authenticateThreeDSOrderUrl,

Expand Down Expand Up @@ -210,6 +212,7 @@ export const PaymentProvider: FC<
!!setRatepayMessage,
enableVaulting
);

const createOrderResult = await createOrder(
requestHeader,
createOrderUrl,
Expand All @@ -219,6 +222,16 @@ export const PaymentProvider: FC<
...relevantOrderData,
}
);

if (
!createOrderResult ||
(createOrderResult && createOrderResult.ok === false)
) {
notify("Error", "something went wrong");
isLoading(false);
return "";
}

const oldOrderData = orderData;

if (createOrderResult) {
Expand All @@ -245,7 +258,12 @@ export const PaymentProvider: FC<
oldOrderData.googlePayData.paymentData.paymentMethodData,
});
if (status === "APPROVED") {
onSuccess(orderData);
handleOnApprove({ orderID: orderData.id }).then(() =>
onSuccess(orderData)
);
} else if (status === "PAYER_ACTION_REQUIRED") {
//@todo 3DS implementation
return "";
} else {
return "";
}
Expand Down Expand Up @@ -298,6 +316,12 @@ export const PaymentProvider: FC<
saveCard
);

//@ts-ignore
if (onApproveResult.ok === false) {
isLoading(false);
notify("Error", "There was an error completing the payment");
return;
}
const { orderData } = onApproveResult as OnApproveResponse;
if (orderData.status === "COMPLETED") {
setShowResult(true);
Expand Down
21 changes: 21 additions & 0 deletions src/components/GooglePay/GooglePay.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { render, screen, waitFor } from "@testing-library/react";
import { GooglePay } from "./GooglePay";

import { GooglePayTestParams } from "./constants";

const MockText: string = "GooglePayMask";
jest.mock("./GooglePayMask", () => ({
GooglePayMask: () => <div>{MockText}</div>,
}));

jest.mock("../../app/loadScript", () => ({
__esModule: true,
default: () => Promise.resolve(),
}));

test("GooglePay is shown", async () => {
render(<GooglePay {...GooglePayTestParams} />);
await waitFor(() => {
expect(screen).toBeDefined();
});
});
6 changes: 6 additions & 0 deletions src/components/GooglePay/GooglePay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export const GooglePay: React.FC<
shippingMethodId,
cartInformation,
createOrderUrl,
getOrderUrl,
onApproveUrl,
purchaseCallback,
getUserInfoUrl,
Expand All @@ -24,6 +25,8 @@ export const GooglePay: React.FC<
allowedCardAuthMethods,
callbackIntents,
environment,
totalPriceStatus,
verificationMethod,
}) => {
return (
<RenderTemplate
Expand All @@ -35,6 +38,7 @@ export const GooglePay: React.FC<
shippingMethodId={shippingMethodId}
cartInformation={cartInformation}
createOrderUrl={createOrderUrl}
getOrderUrl={getOrderUrl}
onApproveUrl={onApproveUrl}
purchaseCallback={purchaseCallback}
getUserInfoUrl={getUserInfoUrl}
Expand All @@ -47,6 +51,8 @@ export const GooglePay: React.FC<
apiVersion={apiVersion}
apiVersionMinor={apiVersionMinor}
environment={environment}
totalPriceStatus={totalPriceStatus}
verificationMethod={verificationMethod}
/>
</RenderTemplate>
);
Expand Down
28 changes: 28 additions & 0 deletions src/components/GooglePay/GooglePayButton.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { render, screen } from "@testing-library/react";
import { GooglePayTestParams } from "./constants";
import { GooglePayMask } from "./GooglePayMask";

const MockText: string = "GooglePayMask";
jest.mock("./GooglePayMask", () => ({
GooglePayMask: () => <div>{MockText}</div>,
}));

jest.mock("../../app/usePayment", () => ({
usePayment: () => {
return { paymentInfo: { id: "123" } };
},
}));

jest.mock("../../app/useHandleCreatePayment", () => ({
useHandleCreatePayment: () => {
return {};
},
}));

test("GooglePayButton is shown", () => {
render(<GooglePayMask {...GooglePayTestParams} />);
expect(screen).toBeDefined();

const googlePayMask = screen.getByText(MockText);
expect(googlePayMask).toBeDefined();
});
4 changes: 4 additions & 0 deletions src/components/GooglePay/GooglePayButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ export const GooglePayButton: React.FC<GooglePayOptionsType> = ({
allowedCardAuthMethods,
callbackIntents,
environment,
totalPriceStatus,
verificationMethod,
}) => {
const { isLoading } = useLoader();
const scriptUrl: string = "https://pay.google.com/gp/p/js/pay.js";
Expand Down Expand Up @@ -46,6 +48,8 @@ export const GooglePayButton: React.FC<GooglePayOptionsType> = ({
apiVersion={apiVersion}
apiVersionMinor={apiVersionMinor}
environment={environment}
totalPriceStatus={totalPriceStatus}
verificationMethod={verificationMethod}
/>
) : (
<></>
Expand Down
19 changes: 19 additions & 0 deletions src/components/GooglePay/GooglePayMask.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { render, screen, waitFor } from "@testing-library/react";
import { GooglePayTestParams } from "./constants";
import { GooglePayMask } from "./GooglePayMask";

jest.mock("../../app/loadScript", () => ({
__esModule: true,
default: () => Promise.resolve(),
}));

jest.mock("./GooglePayMask", () => ({
GooglePayMask: () => <div>mock</div>,
}));

test("GooglePayMask is shown", async () => {
render(<GooglePayMask {...GooglePayTestParams} />);
await waitFor(() => {
expect(screen).toBeDefined();
});
});
Loading

0 comments on commit 417cf9a

Please sign in to comment.