@qrph/qrph
Version:
Library for parsing and encoding QRPH strings.
55 lines (49 loc) • 1.78 kB
text/typescript
import type { UnstructuredEMVQRData } from "@qrph/emv-qr";
import { constants, decodeEMVQR } from "@qrph/emv-qr";
import type { QRPHData, RootQRInfo } from "./schema.js";
import {
POINT_OF_INITIATION_METHOD_MAP,
zQRPHRecipientInfo,
zRootQRInfo,
} from "./schema.js";
const decodeRootQRInfo = (root: UnstructuredEMVQRData): RootQRInfo => {
return zRootQRInfo.parse({
pointOfInitiationMethod:
POINT_OF_INITIATION_METHOD_MAP[
// eslint-disable-next-line @typescript-eslint/no-base-to-string
root[constants.ID.IDPointOfInitiationMethod]?.toString() ?? ""
],
merchantCategoryCode: root[constants.ID.IDMerchantCategoryCode],
transactionCurrency: root[constants.ID.IDTransactionCurrency],
transactionAmount: root[constants.ID.IDTransactionAmount],
countryCode: root[constants.ID.IDCountryCode],
merchantName: root[constants.ID.IDMerchantName],
merchantCity: root[constants.ID.IDMerchantCity],
postalCode: root[constants.ID.IDPostalCode],
});
};
const decodeRecipient = (
data: UnstructuredEMVQRData,
): QRPHData["recipient"] => {
return zQRPHRecipientInfo.parse({
type: data["00"],
bankCode: data["01"],
accountNumber: data["03"],
});
};
export const decodeQRPH = (data: UnstructuredEMVQRData): QRPHData => {
const root = decodeRootQRInfo(data);
const recipient = data["27"] ?? data["28"];
if (!recipient || typeof recipient === "string") {
throw new Error("QRPH data is missing recipient information");
}
return {
...root,
recipient: decodeRecipient(recipient),
_raw: data as Record<string, string | Record<string, string>>,
};
};
export const decodeQRPHFromText = (text: string): QRPHData => {
const emvQRData = decodeEMVQR(text);
return decodeQRPH(emvQRData);
};