voucher-ts
Version:
TypeScript SDK for redeeming TrueWallet vouchers (zero dependencies)
8 lines (7 loc) • 6.47 kB
Source Map (JSON)
{
"version": 3,
"sources": ["../src/validation.ts", "../src/index.ts"],
"sourcesContent": ["export class ValidationError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ValidationError\";\n }\n}\n\nexport const TRUEWALLET_URL_REGEX =\n /^https:\\/\\/gift\\.truemoney\\.com\\/campaign\\/\\?v=[a-zA-Z0-9]+$/;\n\nexport function validateVoucherUrl(url: string): void {\n if (!url) {\n throw new ValidationError(\"\u0E01\u0E23\u0E38\u0E13\u0E32\u0E01\u0E23\u0E2D\u0E01 URL\");\n }\n\n if (!TRUEWALLET_URL_REGEX.test(url)) {\n throw new ValidationError(\"URL \u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07\");\n }\n}\n\nexport function extractVoucherHash(url: string): string {\n const match = url.match(/\\?v=([a-zA-Z0-9]+)/);\n if (!match) {\n throw new ValidationError(\"Invalid voucher URL format\");\n }\n return match[1];\n}\n", "import {\n TrueWalletConfig,\n TrueWalletResult,\n TrueWalletVoucherResponse,\n TrueWalletStatusCode,\n} from \"./types\";\nimport {\n validateVoucherUrl,\n extractVoucherHash,\n ValidationError,\n} from \"./validation\";\n\nconst ERROR_MESSAGES: Record<TrueWalletStatusCode, string> = {\n TARGET_USER_REDEEMED: \"\u0E0B\u0E2D\u0E07\u0E02\u0E2D\u0E07\u0E02\u0E27\u0E31\u0E0D\u0E19\u0E35\u0E49\u0E16\u0E39\u0E01\u0E43\u0E0A\u0E49\u0E44\u0E1B\u0E41\u0E25\u0E49\u0E27\",\n INTERNAL_ERROR: \"\u0E44\u0E21\u0E48\u0E1E\u0E1A\u0E0B\u0E2D\u0E07\u0E02\u0E2D\u0E07\u0E02\u0E27\u0E31\u0E0D\u0E2B\u0E23\u0E37\u0E2D URL \u0E1C\u0E34\u0E14\u0E1E\u0E25\u0E32\u0E14\",\n CANNOT_GET_OWN_VOUCHER: \"\u0E44\u0E21\u0E48\u0E2A\u0E32\u0E21\u0E32\u0E23\u0E16\u0E43\u0E0A\u0E49\u0E0B\u0E2D\u0E07\u0E02\u0E2D\u0E07\u0E02\u0E27\u0E31\u0E0D\u0E02\u0E2D\u0E07\u0E15\u0E31\u0E27\u0E40\u0E2D\u0E07\u0E44\u0E14\u0E49\",\n VOUCHER_EXPIRED: \"\u0E0B\u0E2D\u0E07\u0E02\u0E2D\u0E07\u0E02\u0E27\u0E31\u0E0D\u0E2B\u0E21\u0E14\u0E2D\u0E32\u0E22\u0E38\u0E41\u0E25\u0E49\u0E27\",\n VOUCHER_OUT_OF_STOCK: \"\u0E0B\u0E2D\u0E07\u0E02\u0E2D\u0E07\u0E02\u0E27\u0E31\u0E0D\u0E16\u0E39\u0E01\u0E43\u0E0A\u0E49\u0E44\u0E1B\u0E41\u0E25\u0E49\u0E27\",\n VOUCHER_NOT_FOUND: \"\u0E44\u0E21\u0E48\u0E1E\u0E1A\u0E0B\u0E2D\u0E07\u0E02\u0E2D\u0E07\u0E02\u0E27\u0E31\u0E0D\u0E19\u0E35\u0E49\",\n SUCCESS: \"\u0E2A\u0E33\u0E40\u0E23\u0E47\u0E08\",\n};\n\nexport class TrueWalletVoucher {\n private config: TrueWalletConfig;\n\n constructor(config: TrueWalletConfig) {\n this.config = config;\n }\n\n async redeem(url: string): Promise<TrueWalletResult> {\n try {\n // Validate URL format\n validateVoucherUrl(url);\n\n // Extract hash from URL\n const hash = extractVoucherHash(url);\n\n // Make API request\n const response = await fetch(\n `https://gift.maythiwat.com/campaign/vouchers/${hash}/redeem`,\n {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n mobile: this.config.mobile,\n voucher_hash: hash,\n }),\n }\n );\n\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n const result = (await response.json()) as TrueWalletVoucherResponse;\n\n // Handle non-success cases\n if (result.status.code !== \"SUCCESS\") {\n return {\n error:\n ERROR_MESSAGES[result.status.code] || \"\u0E40\u0E01\u0E34\u0E14\u0E02\u0E49\u0E2D\u0E1C\u0E34\u0E14\u0E1E\u0E25\u0E32\u0E14\u0E01\u0E31\u0E1A\u0E0B\u0E2D\u0E07\u0E02\u0E2D\u0E07\u0E02\u0E27\u0E31\u0E0D\",\n code: result.status.code,\n };\n }\n\n // Handle success case\n if (!result.data?.voucher) {\n return {\n error: \"Invalid response format\",\n code: \"INTERNAL_ERROR\",\n };\n }\n\n const stringAmt = result.data.voucher.redeemed_amount_baht.replace(\n /,/g,\n \"\"\n );\n const amount = Number(stringAmt);\n\n if (isNaN(amount)) {\n return {\n error: \"Invalid amount format\",\n code: \"INTERNAL_ERROR\",\n };\n }\n\n return {\n amount,\n originalData: result,\n };\n } catch (error) {\n if (error instanceof ValidationError) {\n return {\n error: error.message,\n code: \"INTERNAL_ERROR\",\n };\n }\n\n if (error instanceof Error) {\n return {\n error: error.message,\n code: \"INTERNAL_ERROR\",\n };\n }\n\n return {\n error: \"Unknown error occurred\",\n code: \"INTERNAL_ERROR\",\n };\n }\n }\n}\n\nexport * from \"./types\";\nexport * from \"./validation\";\n"],
"mappings": "AAAO,IAAMA,EAAN,cAA8B,KAAM,CACzC,YAAYC,EAAiB,CAC3B,MAAMA,CAAO,EACb,KAAK,KAAO,iBACd,CACF,EAEaC,EACX,+DAEK,SAASC,EAAmBC,EAAmB,CACpD,GAAI,CAACA,EACH,MAAM,IAAIJ,EAAgB,4DAAe,EAG3C,GAAI,CAACE,EAAqB,KAAKE,CAAG,EAChC,MAAM,IAAIJ,EAAgB,kEAAgB,CAE9C,CAEO,SAASK,EAAmBD,EAAqB,CACtD,IAAME,EAAQF,EAAI,MAAM,oBAAoB,EAC5C,GAAI,CAACE,EACH,MAAM,IAAIN,EAAgB,4BAA4B,EAExD,OAAOM,EAAM,CAAC,CAChB,CCdA,IAAMC,EAAuD,CAC3D,qBAAsB,yJACtB,eAAgB,oKAChB,uBAAwB,+MACxB,gBAAiB,iIACjB,qBAAsB,uIACtB,kBAAmB,+GACnB,QAAS,sCACX,EAEaC,EAAN,KAAwB,CAG7B,YAAYC,EAA0B,CACpC,KAAK,OAASA,CAChB,CAEA,MAAM,OAAOC,EAAwC,CACnD,GAAI,CAEFC,EAAmBD,CAAG,EAGtB,IAAME,EAAOC,EAAmBH,CAAG,EAG7BI,EAAW,MAAM,MACrB,gDAAgDF,CAAI,UACpD,CACE,OAAQ,OACR,QAAS,CACP,eAAgB,kBAClB,EACA,KAAM,KAAK,UAAU,CACnB,OAAQ,KAAK,OAAO,OACpB,aAAcA,CAChB,CAAC,CACH,CACF,EAEA,GAAI,CAACE,EAAS,GACZ,MAAM,IAAI,MAAM,uBAAuBA,EAAS,MAAM,EAAE,EAG1D,IAAMC,EAAU,MAAMD,EAAS,KAAK,EAGpC,GAAIC,EAAO,OAAO,OAAS,UACzB,MAAO,CACL,MACER,EAAeQ,EAAO,OAAO,IAAI,GAAK,qKACxC,KAAMA,EAAO,OAAO,IACtB,EAIF,GAAI,CAACA,EAAO,MAAM,QAChB,MAAO,CACL,MAAO,0BACP,KAAM,gBACR,EAGF,IAAMC,EAAYD,EAAO,KAAK,QAAQ,qBAAqB,QACzD,KACA,EACF,EACME,EAAS,OAAOD,CAAS,EAE/B,OAAI,MAAMC,CAAM,EACP,CACL,MAAO,wBACP,KAAM,gBACR,EAGK,CACL,OAAAA,EACA,aAAcF,CAChB,CACF,OAASG,EAAO,CACd,OAAIA,aAAiBC,EACZ,CACL,MAAOD,EAAM,QACb,KAAM,gBACR,EAGEA,aAAiB,MACZ,CACL,MAAOA,EAAM,QACb,KAAM,gBACR,EAGK,CACL,MAAO,yBACP,KAAM,gBACR,CACF,CACF,CACF",
"names": ["ValidationError", "message", "TRUEWALLET_URL_REGEX", "validateVoucherUrl", "url", "extractVoucherHash", "match", "ERROR_MESSAGES", "TrueWalletVoucher", "config", "url", "validateVoucherUrl", "hash", "extractVoucherHash", "response", "result", "stringAmt", "amount", "error", "ValidationError"]
}