Skip to content

Instantly share code, notes, and snippets.

@DogAndHerDude
Last active July 29, 2021 17:53
Show Gist options
  • Save DogAndHerDude/258962ae4c09dc08c95b70b3deab6ddb to your computer and use it in GitHub Desktop.
Save DogAndHerDude/258962ae4c09dc08c95b70b3deab6ddb to your computer and use it in GitHub Desktop.
import * as React from 'react';
import * as ReactDOM from 'react';
interface IProps {
clientID: string;
currency: string;
label: string;
layout: string;
shape: string;
color: string;
tagline: boolean;
}
export default class PaypalButton extends React.PureComponent<IProps, {}> {
private PAYPAL_BUTTON;
private scriptNode: HTMLScriptElement;
public componentDidMount(): void {
this.loadScript();
}
public componentDidUpdate(prevProps: IProps): void {
if (this.props.clientID !== prevProps.clientID || this.props.currency !== prevProps.currency) {
// Script needs to be reloaded if any script source search string keys change values
this.loadScript();
}
}
public render(): React.ReactNode {
switch (true) {
case this.PAYPAL_BUTTON === void 0:
return null;
default:
return (
<this.PAYPAL_BUTTON
key={this.generateKey()}
createOrder={this.createOrder}
onApprove={this.onApprove}
onCancel={this.onCancel}
style={{
label: 'checkout', // buynow | checkout | pay
layout: 'vertical', // vertical | horizontal
shape: 'rect', // pill | rect
color: 'black', // gold | blue | silver | black
tagline: true, // true | false
}}
/>
);
}
private loadScript(): void {
if (this.scriptExists()) {
return;
}
if (this.scriptNode !== void 0) {
document.body.removeChild(this.scriptNode);
}
const source = this.getScriptSrc();
const node = document.createElement('script');
node.src = source;
node.onload = this.onScriptLoad;
node.onerror = this.onScriptLoadError;
document.body.appendChild(node);
this.currentNode = node;
}
private scriptExists(): boolean {
const source = this.getScriptSrc();
const node = document.querySelector(`script[src="${source}"]`);
return node !== void 0 && node !== null;
}
private getScriptSrc(): string {
return `https://www.paypal.com/sdk/js?client-id=${this.props.clientID || 'sb'}&currency=${this.props.currency || 'USD'}`;
}
private onScriptLoad = (evt: Event): void => {
this.configureButton();
this.forceUpdate();
}
private onScriptLoadError = (evt: string | Event): void => {
console.error(evt);
}
private configureButton(): void {
if (window.paypal === void 0) {
return;
}
this.PAYPAL_BUTTON = window.paypal.Buttons.driver('react', { React, ReactDOM });
}
private generateKey(): string {
// Used to force update if one of the props changes that impacts the style of the button
// Button does not update otherwise
const { label, layout, shape, color, tagline } = this.props;
return `${label}.${layout}.${shape}.${color}.${tagline}`;
}
private createOrder = (data, actions): void => {
// Impl
}
private onApprove = (data, actions): void => {
// Impl
}
private onCancel = (data, actions): void => {
// Impl
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment