Skip to content

Commit

Permalink
fix: phone number issue
Browse files Browse the repository at this point in the history
  • Loading branch information
Govind Diwakar committed May 22, 2024
1 parent 503b066 commit f0c9c07
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 50 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ node_modules
.DS_store
yarn.lock
*.log
*.env*
*.env*
*.tgz
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ const plugins = [
key_id: process.env.RAZORPAY_ID,
key_secret: process.env.RAZORPAY_SECRET,
razorpay_account: process.env.RAZORPAY_ACCOUNT,
automatic_expiry_period: 30, /*any value between 12minuts and 30 days expressed in minutes*/
automatic_expiry_period: 30, /*any value between 12 minutes and 30 days expressed in minutes*/
manual_expiry_period: 20,
refund_speed: "normal",
webhook_secret: process.env.RAZORPAY_SECRET,
Expand All @@ -66,7 +66,7 @@ const plugins = [
## Client side configuration
For the nextjs start you need to make the following changes
For the NextJs start you need to make the following changes
1. Install package to your next starter. This just makes it easier, importing all the scripts implicitly
```
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "medusa-payment-razorpay",
"version": "7.1.3",
"description": "Razorpay Payment provider for Meduas Commerce",
"version": "7.1.3-next-9",
"description": "Razorpay Payment provider for Medusa Commerce",
"main": "dist/index.js",
"repository": {
"type": "git",
Expand Down
2 changes: 1 addition & 1 deletion src/core/__tests__/razorpay-base.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ describe("RazorpayTest", () => {
);

if (isMocksEnabled()) {
expect(RazorpayMock.customers.create).toHaveBeenCalled();
expect(RazorpayMock.orders.create).toHaveBeenCalled();

/* expect(RazorpayMock.customers.create).toHaveBeenCalledWith({
email: initiatePaymentContextWithExistingCustomer.email,
Expand Down
162 changes: 118 additions & 44 deletions src/core/razorpay-base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { Orders } from "razorpay/dist/types/orders";
import crypto from "crypto";
import { Refunds } from "razorpay/dist/types/refunds";
import { Customers } from "razorpay/dist/types/customers";
import { Payments } from "razorpay/dist/types/payments";

/**
* The paymentIntent object corresponds to a razorpay order.
Expand Down Expand Up @@ -118,7 +119,14 @@ abstract class RazorpayBase extends AbstractPaymentProcessor {
paymentSessionData: Record<string, unknown>
): Promise<PaymentSessionStatus> {
const id = paymentSessionData.id as string;
const paymentIntent = await this.razorpay_.orders.fetch(id);
const orderId = paymentSessionData.order_id as string;
let paymentIntent: Orders.RazorpayOrder;
try {
paymentIntent = await this.razorpay_.orders.fetch(id);
} catch (e) {
this.logger.warn("received payment data from session not order data");
paymentIntent = await this.razorpay_.orders.fetch(orderId);
}

switch (paymentIntent.status) {
// created' | 'authorized' | 'captured' | 'refunded' | 'failed'
Expand Down Expand Up @@ -209,7 +217,7 @@ abstract class RazorpayBase extends AbstractPaymentProcessor {
);
razorpayCustomer = updateRazorpayCustomer;
} catch (e) {
this.logger.error(
this.logger.warn(
"unable to edit customer in the razorpay payment processor"
);
}
Expand All @@ -229,7 +237,7 @@ abstract class RazorpayBase extends AbstractPaymentProcessor {
);
}
}
return razorpayCustomer; // returning un modifed razorpay customer
return razorpayCustomer; // returning un modified razorpay customer
}

async createRazorpayCustomer(
Expand All @@ -239,21 +247,31 @@ abstract class RazorpayBase extends AbstractPaymentProcessor {
intentRequest
): Promise<Customers.RazorpayCustomer | undefined> {
let razorpayCustomer: Customers.RazorpayCustomer;
const phone =
cart?.billing_address?.phone ??
customer.phone ??
customer?.billing_address?.phone;
const gstin =
(cart?.billing_address as any)?.gstin ??
(customer?.metadata?.gstin as string) ??
undefined;
if (!phone || !email) {
throw new Error(
"Razorpay-Provider didn't receive email or " +
"phone number to create razorpay customer"
);
}
const firstName =
cart?.billing_address.first_name ?? customer.first_name ?? "";
const lastName =
cart?.billing_address.last_name ?? customer.last_name ?? "";
try {
const customerParams: Customers.RazorpayCustomerCreateRequestBody = {
email,
contact:
cart?.billing_address?.phone ??
customer.phone ??
customer?.billing_address?.phone,
gstin:
(cart?.billing_address as any)?.gstin ??
(customer?.metadata?.gstin as string) ??
undefined,
contact: phone,
gstin: gstin,
fail_existing: 0,
name: `${
cart?.billing_address.first_name ?? customer.first_name ?? ""
} ${cart.billing_address.last_name ?? customer.last_name ?? ""}`,
name: `${firstName} ${lastName} `,
notes: {
updated_at: new Date().toISOString(),
},
Expand Down Expand Up @@ -441,7 +459,10 @@ abstract class RazorpayBase extends AbstractPaymentProcessor {
);
}
} catch (e) {
this.logger.error(`unanble to create customer ${e.message}`);
return this.buildError(
"An error occurred in creating customer request",
e
);
}

return {
Expand Down Expand Up @@ -572,44 +593,87 @@ abstract class RazorpayBase extends AbstractPaymentProcessor {
): Promise<
PaymentProcessorError | PaymentProcessorSessionResponse["session_data"]
> {
let intent;
try {
const id = (paymentSessionData as unknown as Orders.RazorpayOrder)
.id as string;
const intent = await this.razorpay_.orders.fetch(id);
return intent as unknown as PaymentProcessorSessionResponse["session_data"];
intent = await this.razorpay_.orders.fetch(id);
} catch (e) {
return this.buildError("An error occurred in retrievePayment", e);
const id = (paymentSessionData as unknown as Payments.RazorpayPayment)
.order_id as string;
try {
intent = await this.razorpay_.orders.fetch(id);
} catch (e) {
this.buildError("An error occurred in retrievePayment", e);
}
}
return intent as unknown as PaymentProcessorSessionResponse["session_data"];
}

async updatePayment(
context: PaymentProcessorContext
): Promise<PaymentProcessorError | PaymentProcessorSessionResponse | void> {
const { amount, customer, paymentSessionData, currency_code, resource_id } =
context;
const cart = await this.cartService.retrieve(resource_id, {
relations: ["billing_address"],
});
const razorpayId =
customer?.metadata?.razorpay_id ||
(customer?.metadata as any)?.razopay?.rp_customer_id;
let cart: Cart;
try {
cart = await this.cartService.retrieve(resource_id, {
relations: ["billing_address"],
});

if (!customer) {
return;
if (!cart.billing_address) {
return;
}
} catch {
return this.buildError(
"An error occurred in updatePayment during the retrieve of the cart",
new Error(
"An error occurred in updatePayment during the retrieve of the cart"
)
);
}
let refreshedCustomer: Customer;
let customerPhone = "";
let razorpayId;
if (customer) {
try {
refreshedCustomer = await this.customerService.retrieve(customer.id, {
relations: ["billing_address"],
});
razorpayId =
refreshedCustomer?.metadata?.razorpay_id ||
(refreshedCustomer?.metadata as any)?.razopay?.rp_customer_id;
customerPhone =
refreshedCustomer?.phone ?? refreshedCustomer?.billing_address?.phone;
if (!refreshedCustomer.billing_address) {
return this.buildError(
"no customer billing found",
new Error(
"no customer billing found " +
refreshedCustomer.billing_address_id
)
);
}
} catch {
return this.buildError(
"An error occurred in updatePayment during the retrieve of the customer",
new Error(
"An error occurred in updatePayment during the retrieve of the customer"
)
);
}
}
const isCartNonEmptyPhone =
cart?.billing_address?.phone && cart?.billing_address?.phone != "";

if (razorpayId !== (paymentSessionData?.customer as any)?.id) {
const phone =
cart?.billing_address?.phone != ""
? cart?.billing_address?.phone
: customer?.phone ?? customer?.billing_address?.phone;
const phone = isCartNonEmptyPhone
? cart?.billing_address?.phone
: customerPhone;

if (!phone) {
throw new MedusaError(
MedusaError.Types.PAYMENT_AUTHORIZATION_ERROR,
"Phone number not found in context",
MedusaError.Codes.CART_INCOMPATIBLE_STATE
);
this.logger.warn("phone number wasn't specified");
return;
}
const result = await this.initiatePayment(context);
if (isPaymentProcessorError(result)) {
Expand All @@ -622,7 +686,10 @@ abstract class RazorpayBase extends AbstractPaymentProcessor {
return result;
} else {
if (!amount && !currency_code) {
return;
return this.buildError(
"amount or currency_code not supported",
new Error("the phone number wasn't specified")
);
}

try {
Expand Down Expand Up @@ -661,14 +728,21 @@ abstract class RazorpayBase extends AbstractPaymentProcessor {
"Cannot update amount, use updatePayment instead"
);
}
const paymentSession = await this.razorpay_.payments.fetch(sessionId);
if (data.notes) {
const result = (await this.razorpay_.orders.edit(sessionId, {
notes: { ...paymentSession.notes, ...data.notes },
})) as unknown as PaymentProcessorSessionResponse["session_data"];
return result;
} else {
return paymentSession as unknown as PaymentProcessorSessionResponse["session_data"];
try {
const paymentSession = await this.razorpay_.payments.fetch(
(data.data as Record<string, any>).id as string
);
if (data.notes) {
const result = (await this.razorpay_.orders.edit(sessionId, {
notes: { ...paymentSession.notes, ...data.notes },
})) as unknown as PaymentProcessorSessionResponse["session_data"];
return result;
} else {
this.logger.warn("only notes can be updated in razorpay order");
return paymentSession as unknown as PaymentProcessorSessionResponse["session_data"];
}
} catch (e) {
return (data as Record<string, any>).data ?? data;
}
} catch (e) {
return this.buildError("An error occurred in updatePaymentData", e);
Expand Down

0 comments on commit f0c9c07

Please sign in to comment.