Skip to content

Instantly share code, notes, and snippets.

@sagrawal31
Last active May 15, 2023 15:12
Show Gist options
  • Save sagrawal31/3471820b4f58024990cf888ae4c87377 to your computer and use it in GitHub Desktop.
Save sagrawal31/3471820b4f58024990cf888ae4c87377 to your computer and use it in GitHub Desktop.
Angular & Typescript wrapper around Razorpay checkout to be quickly used in any Angular/Ionic application
/**
* Example component file
*/
import {Component, NgZone} from '@angular/core';
import {RazorpayWrapper} from '../utils/razorpay/wrapper';
@Component({
selector: 'app-home',
templateUrl: 'home.page.html',
styleUrls: ['home.page.scss']
})
export class HomePage {
constructor(private ngZone: NgZone) {
}
async init() {
const wrapper = new RazorpayWrapper(this.ngZone);
const options = {
description: 'Foo Description',
key: 'rzp_test_key', // Change this
order_id: 'order_EGuCtoQhdlJLIf', // Change this
amount: 100,
name: 'Foo',
prefill: {
email: 'john@example.com',
contact: '9876543210',
name: 'Shashank Agrawal'
}
};
try {
const data = await wrapper.open(options);
console.log(data);
} catch (e) {
console.error(e);
}
}
}
export interface RazorpayOption {
name: string;
description?: string;
key: string;
order_id: string;
amount: number;
prefill: RazorpayPrefill;
modal: any;
notes?: any;
theme?: any;
external?: RazorpayExternalOption;
handler?: (response: any) => void;
}
export interface RazorpayExternalOption {
wallets: Array<string>;
handler: (response: any) => void;
}
export interface RazorpayPrefill {
email?: string;
contact?: string;
name?: string;
method?: 'card' | 'netbanking' | 'wallet' | 'emi' | 'upi';
}
export interface RazorpayResponse {
razorpay_payment_id: string;
razorpay_order_id: string;
razorpay_signature: string;
}
export interface RazorpayError {
code: number;
description: string;
}
import {NgZone} from '@angular/core';
import {RazorpayOption} from './models';
/**
* A TypeScript and Angular wrapper around the JavaScript layer of Razorpay integration.
* Copied and modified from https://github.com/razorpay/razorpay-cordova/blob/master/src/browser/CheckoutProxy.js
*
* @author Shashank Agrawal
*/
export class RazorpayWrapper {
private readonly SCRIPT_ID = 'rzp-js-sdk';
private scriptElement: HTMLScriptElement;
/**
* @param ngZone Angular's instance of {@link NgZone} to run the resolve() & reject() operations in the context of Angular.
*/
constructor(private ngZone: NgZone) {
}
/**
* Inject the script https://checkout.razorpay.com/v1/checkout.js in the <head> tag if not already.
*
* @returns a promise which will be resolved when the script is injected and loaded completely.
*/
private injectRZPScript(): Promise<any> {
this.scriptElement = document.getElementById(this.SCRIPT_ID) as HTMLScriptElement;
if (this.scriptElement) {
return;
}
this.scriptElement = document.createElement('script');
this.scriptElement.id = this.SCRIPT_ID;
const promise = new Promise((resolve, reject) => {
this.scriptElement.onload = () => {
this.ngZone.run(() => {
resolve();
});
};
this.scriptElement.onerror = () => {
this.ngZone.run(() => {
reject({code: 0, description: 'Network error'});
});
};
});
this.scriptElement.src = 'https://checkout.razorpay.com/v1/checkout.js';
document.head.appendChild(this.scriptElement);
return promise;
}
/**
* Open the Razorypay modal and show the payment options.
*
* @param options different options to be passed to Razorpay.
* @returns a promise which will be resolved on successful payment. Rejected if the modal is closed by the user or payment fails.
*/
private openRZP(options: RazorpayOption): Promise<any> {
options.modal = options.modal || {};
const promise = new Promise((resolve, reject) => {
options.modal.ondismiss = () => {
this.ngZone.run(() => {
reject({code: 2, description: 'Payment cancelled by user'});
});
};
options.handler = (response) => {
this.ngZone.run(() => {
resolve(response);
});
};
if (options.external && options.external.wallets && options.external.wallets.length) {
options.external.handler = (response) => {
response.external_wallet_name = response.wallet;
this.ngZone.run(() => {
reject(response);
});
};
}
});
const Razorpay = (window as any).Razorpay;
new Razorpay(options).open();
return promise;
}
/**
* Entry point for the Razorpay standard checkout option. This will inject the checkout.js script (if not already) and then
* initiates the payment modal.
*
* @param options different options to be passed to Razorpay.
* @returns a promise which will be resolved on successful payment. Rejected if the modal is closed by the user or payment fails.
*/
async open(options: RazorpayOption): Promise<any> {
const Razorpay = (window as any).Razorpay;
if (!Razorpay) {
await this.injectRZPScript();
}
return await this.openRZP(options);
}
}
@rohanrajpal
Copy link

Lovely!

@sagrawal31
Copy link
Author

Glad you liked it @rohanrajpal!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment