-
Notifications
You must be signed in to change notification settings - Fork 114
feat: added upi intent qr and collect flow #1284
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
webpack.common.js
Outdated
| // UPI App URLs for PaymentRequest API | ||
| "https://tez.google.com/pay", | ||
| "https://mercury.phonepe.com/transact/pay", | ||
| "https://securegw.paytm.in/order/sendpaymentrequest", | ||
| "https://payments.juspay.in/bhim/pay", | ||
| "https://cred-web-stg.dreamplug.in/checkout/pay", | ||
| "https://cred.club/checkout/pay", | ||
| "https://gokiwi.in/pay", | ||
| "https://pl.navifinserv.com/payments-gateway", | ||
| "https://super.money/pay", | ||
| "https://promotions.mobikwik.com/epay/payments-gateway/", | ||
| "https://moneyview.in/payment/", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I found that some UPI APIs are common in both script and connect sources. Please maintain a separate array for them, similar to localhostSources in this file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
src/GlobalVars.res
Outdated
| @val external backendEndPoint: string = "backendEndPoint" | ||
| @val external confirmEndPoint: string = "confirmEndPoint" | ||
| @val external sdkUrl: string = "sdkUrl" | ||
| // let sdkUrl = "https://9d18ffafef48f6.lhr.life" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove it
|
|
||
| let isItInappBrowser = () => { | ||
| try { | ||
| let ua = navigator.userAgent->String.toLowerCase | ||
| ua->String.includes("instagram") || ua->String.includes("fbav") | ||
| } catch { | ||
| | _error => false | ||
| } | ||
| } | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you explain why you’re wrapping isItInappBrowser in a try-catch block? You didn’t do the same in getMobileOperatingSystem.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When detecting isItInappBrowser, It might get called in restricted environments, whereas it is not the case with getMobileOperatingSystem
src/Payments/UPIDisplay.res
Outdated
| dict | ||
| ->Dict.get("app") | ||
| ->Option.getOr(JSON.Encode.null) | ||
| ->JSON.Decode.string | ||
| ->Option.getOr("") | ||
|
|
||
| let packageName = | ||
| dict | ||
| ->Dict.get("packageName") | ||
| ->Option.getOr(JSON.Encode.null) | ||
| ->JSON.Decode.string | ||
| ->Option.getOr("") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use getStringFromDict
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added Utility function getStringFromDict, changed previous one to getStringFromOptionalDict
src/Payments/UPIDisplay.res
Outdated
| let headersDict = | ||
| metaDataDict | ||
| ->getJsonObjectFromDict("headers") | ||
| ->JSON.Decode.object | ||
| ->Option.getOr(Dict.make()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use getDictFromDict
| <RenderIf condition={paymentMethodType === "upi_qr"}> | ||
| <UPIQRCode upiUrl timeRemaining /> | ||
| </RenderIf> | ||
| <RenderIf condition={paymentMethodType !== "upi_qr"}> | ||
| <UPIAvailableAppsModal availableApps selectedApp setSelectedApp /> | ||
| </RenderIf> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we do like this? use ternary operator
{
paymentMethodType === "upi_qr"?
<UPIQRCode upiUrl timeRemaining /> :
<UPIAvailableAppsModal availableApps selectedApp setSelectedApp />
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I saw that in our code we mostly have <RenderIf> based approach but at places we use ternary operator as well, so which one should be prioritized? @ArushKapoorJuspay @AbhishekChorotiya Can you also comment about this
| <RenderIf condition={paymentMethodType === "upi_qr"}> | ||
| <UPIButtons.DoneButton closeModal /> | ||
| </RenderIf> | ||
| <RenderIf condition={paymentMethodType !== "upi_qr"}> | ||
| <UPIButtons.AppSelectionButton | ||
| selectedApp upiUrl setCurrentScreen setTimeRemaining timer defaultTimer | ||
| /> | ||
| </RenderIf> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here
src/hyper-loader/Elements.res
Outdated
| dict | ||
| ->Dict.get("url") | ||
| ->Option.getOr(JSON.Encode.null) | ||
| ->JSON.Decode.string | ||
| ->Option.getOr("") | ||
| let appName = | ||
| dict | ||
| ->Dict.get("app") | ||
| ->Option.getOr(JSON.Encode.null) | ||
| ->JSON.Decode.string | ||
| ->Option.getOr("") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use getStringFromDict
src/Components/UPIButtons.res
Outdated
| background: themeObj.colorPrimary, | ||
| color: "#ffffff", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you use colors from themeObj?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
| <button | ||
| className="w-full p-3 rounded-lg font-medium" | ||
| style={ | ||
| background: themeObj.colorPrimary, | ||
| color: "#ffffff", | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here
| <RenderIf condition={availableApps->Array.length !== 0}> | ||
| {availableApps | ||
| ->Array.mapWithIndex((obj, i) => | ||
| renderAppButton(obj, i, ~appArrayLen=availableApps->Array.length) | ||
| ) | ||
| ->React.array} | ||
| </RenderIf> | ||
| <RenderIf condition={availableApps->Array.length === 0}> | ||
| <div className="text-center text-gray-500 py-6"> | ||
| {React.string("No UPI apps are available at the moment.")} | ||
| </div> | ||
| </RenderIf> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please use ternary operator here?
Type of Change
Description
#1283
From list of apps detect which ones are available based upon platform and device, and navigate to the soecific app for payment completion
Request
Response
Collect the required fields using SDK and then show a waiting screen for the payment to be done
Request and Response for UPI Collect Flow
Response
Generate the QR Code for the UPI Deep link which can be scanned using any UPI App
Request
Response
Added three new screens - Waiting screen, QR Code display, App selection screen
Added dynamic polling and waiting timer logic based upon the response from confirm api
Polling Object
Relevant Docs, Threads and Repos -
https://developer.mozilla.org/en-US/docs/Web/API/PaymentRequest/PaymentRequest
https://bitbucket.juspay.net/projects/PICAF/repos/qr-generator/browse
https://bitbucket.juspay.net/projects/PICAF/repos/hyper-sdk-web/browse
https://juspay.slack.com/archives/C03V08QDR24/p1759840819011839
https://juspay.slack.com/archives/C04TLRJEY4F/p1760334063176879
Enhancements need to be picked next :-
Maintain App List on S3
Improve Design
Add Locale Support
Move Qr Code library to shared codebase
How did you test it?
Tested UPI Collect via HS
Tested UPI QR and UPI Intent via UCS
https://github.com/user-attachments/assets/9716cf06-eb5c-4a31-a512-829dd6bf07de
https://github.com/user-attachments/assets/1968a982-b194-4a9c-9b10-9f742433c411
Checklist
npm run re:build