Skip to content

Instantly share code, notes, and snippets.

@sirbrillig
Last active March 28, 2021 21:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sirbrillig/ef04d98744efc5e466b8092c75f2a830 to your computer and use it in GitHub Desktop.
Save sirbrillig/ef04d98744efc5e466b8092c75f2a830 to your computer and use it in GitHub Desktop.
import React from "react";
import { render } from "react-dom";
// @ts-ignore
import wpcomFactory from 'wpcom';
import wpcomProxyRequest from 'wpcom-proxy-request';
import {
ShoppingCartProvider,
useShoppingCart,
} from "@automattic/shopping-cart";
import {
getTotalLineItemFromCart,
getLineItemsFromCart,
} from "@automattic/wpcom-checkout";
import type { RequestCart, ResponseCart } from "@automattic/shopping-cart";
import {
CheckoutProvider,
Checkout,
CheckoutStep,
CheckoutStepBody,
CheckoutSteps,
CheckoutStepArea,
getDefaultOrderSummaryStep,
getDefaultOrderReviewStep,
getDefaultPaymentMethodStep,
createPayPalMethod,
makeRedirectResponse,
} from "@automattic/composite-checkout";
// -----------------------
// Types
// -----------------------
declare global {
interface Window {
checkout_data: { blog_id: string };
}
}
type PayPalExpressEndpointRequestPayload = {
success_url: string;
cancel_url: string;
cart: ResponseCart;
country: string;
postal_code: string;
};
// -----------------------
// Functions
// -----------------------
const wpcom = wpcomFactory( wpcomProxyRequest );
async function submitPayPalExpressRequest(
payload: PayPalExpressEndpointRequestPayload
): Promise<string> {
return wpcom.req.post({
path: "/me/paypal-express-url",
method: "POST",
body: payload,
}) as Promise<string>;
}
async function getCart(cartKey: string) {
const response = await wpcom.req.get({
apiVersion: "1.1",
method: "GET",
path: `/me/shopping-cart/${cartKey}`,
});
return response as ResponseCart;
}
async function setCart(cartKey: string, cart: RequestCart) {
const response = await wpcom.req.post({
apiVersion: "1.1",
method: "POST",
path: `/me/shopping-cart/${cartKey}`,
body: cart,
});
return response as ResponseCart;
}
function onPaymentComplete() {
alert("Your payment is complete!");
}
function showErrorMessage(message: string) {
console.error(message);
alert(message);
}
function showInfoMessage(message: string) {
console.log(message);
}
function showSuccessMessage(message: string) {
alert(message);
}
function createPayPalExpressEndpointRequestPayloadFromLineItems({
successUrl,
cancelUrl,
country,
postalCode,
cart,
}: {
successUrl: string;
cancelUrl: string;
country: string;
postalCode: string;
cart: ResponseCart;
}): PayPalExpressEndpointRequestPayload {
return {
success_url: successUrl,
cancel_url: cancelUrl,
cart,
country,
postal_code: postalCode,
};
}
async function payPalProcessor(cart: ResponseCart) {
const successUrl = window.location.href;
const cancelUrl = successUrl;
return submitPayPalExpressRequest(
createPayPalExpressEndpointRequestPayloadFromLineItems({
successUrl,
cancelUrl,
country: cart.tax.location?.country_code ?? "US",
postalCode: cart.tax.location?.postal_code ?? "10001",
cart,
})
).then(makeRedirectResponse);
}
const orderSummaryStep = getDefaultOrderSummaryStep();
const paymentMethodStep = getDefaultPaymentMethodStep();
const reviewOrderStep = getDefaultOrderReviewStep();
const cartKey = window.checkout_data.blog_id;
// -----------------------
// Components
// -----------------------
function MyCheckoutBody() {
return (
<Checkout>
<CheckoutStepArea>
<CheckoutStepBody
completeStepContent={orderSummaryStep.completeStepContent}
titleContent={orderSummaryStep.titleContent}
isStepActive={false}
isStepComplete={true}
stepNumber={1}
stepId={"order-summary"}
/>
<CheckoutSteps>
<CheckoutStep
stepId="review-order-step"
isCompleteCallback={() => true}
activeStepContent={reviewOrderStep.activeStepContent}
completeStepContent={reviewOrderStep.completeStepContent}
titleContent={reviewOrderStep.titleContent}
/>
<CheckoutStep
stepId="payment-method-step"
activeStepContent={paymentMethodStep.activeStepContent}
completeStepContent={paymentMethodStep.completeStepContent}
titleContent={paymentMethodStep.titleContent}
isCompleteCallback={() => false}
/>
</CheckoutSteps>
</CheckoutStepArea>
</Checkout>
);
}
function Cart() {
const { responseCart, isLoading } = useShoppingCart();
const items = getLineItemsFromCart(responseCart);
const total = getTotalLineItemFromCart(responseCart);
const paypalMethod = React.useMemo(() => createPayPalMethod({}), []);
return (
<CheckoutProvider
items={items}
total={total}
onPaymentComplete={onPaymentComplete}
showErrorMessage={showErrorMessage}
showInfoMessage={showInfoMessage}
showSuccessMessage={showSuccessMessage}
isLoading={isLoading}
paymentMethods={[paypalMethod]}
paymentProcessors={{ paypal: () => payPalProcessor(responseCart) }}
initiallySelectedPaymentMethodId={"paypal"}
>
<MyCheckoutBody />
</CheckoutProvider>
);
}
function App({ cartKey }: { cartKey: string }): JSX.Element {
return (
<div>
<h2>Checkout experiment</h2>
<ShoppingCartProvider
cartKey={cartKey}
getCart={getCart}
setCart={setCart}
>
<Cart />
</ShoppingCartProvider>
</div>
);
}
render(
<App cartKey={cartKey} />,
window.document.querySelector("#checkout-experiment-app")
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment