Closed ranka23 closed 2 years ago
As usual, found the answer after posting the issue.
What you can do, if you want to generate the QR Code on the server and send the QR code to the client, instead of sending the encoded url and then doing more work on the front-end to actually generate the QR code.
@solana/pay
lib, yarn add qrcode
(also yarn add -D @types/qrcode
if .ts)import QRCode from "qrcode"
into your file.
import QRCode from "qrcode"
...
const createSolanaOrder = async (_req: Request, res: Response) => {
// get the order details (The encoded url) const url = getOrderDetails()
// Replace the below line from the docs example, which uses the createQR(url) from @solana/pay // -> const qrCode = createQR(url); with the line below
// Where the magic happens. The .toString() is required else it won't work. const qr = await QRCode.toDataURL(url.toString())
// create an html string. You can also use ejs or another template engine
const html = <img src=${qr} >
// send the html string in the response return res.send({ __html: html }) }
Now, I'm a React guy, so on the client, you can do something like this.
import { useEffect, useState } from "react"
const SolanaPay: React.FC = () => { const [html, setHTML] = useState({ __html: "" })
useEffect(() => {
const getSolQR = async () => {
const res = await axios.get<{ __html: "" }>(/checkout/solana
)
setHTML(res.data)
}
getSolQR()
}, [])
return <>{html.__html ?
: }</> }export default SolanaPay
I've tested this with the Phantom wallet. Seems to be working for me.
Personally, I found this to be a much simpler implementation without manipulating the DOM directly or creating refs to access elements.
More importantly, the client is merely painting what data the server returns and not doing more work. Ideally, it should not.
Then again I may be wrong and I've perhaps overlooked something. Maybe the `.toString()` in the controller messes something up in the encoded url? or it's an unsafe implementation. I am not too sure. I'll leave this issue open for now, so others can have a look and pitch in. If this implementation seems acceptable, please feel free to close the issue.
Wish you a pleasant day reader. 😊
Currently, one can't create the QR image on the backend, stick it in an
<img src={...}>
and send the entirehtml
across the wire to the client to render the html directly. This is because the libqr-code-styling.js
requiresdocument
to work.document
is undefined on NodeJS. Since it's related to payments, I would rather want to send the entirehtml
across the wire rather than just the URL and tinker with it on the client. Else the client seems a bit smart taking up some of the server's responsibility. Any idea how we can achieve this? Also, if I'm wrong and this is possible please do correct me. Thank you.