@social-mail/social-mail-web-server 1.4.847 → 1.4.849

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (24) hide show
  1. package/dist/server/seed/ui/seed-ui.js +1 -1
  2. package/dist/server/services/payment-gateways/Gateway.d.ts +13 -3
  3. package/dist/server/services/payment-gateways/Gateway.d.ts.map +1 -1
  4. package/dist/server/services/payment-gateways/Gateway.js +37 -1
  5. package/dist/server/services/payment-gateways/Gateway.js.map +1 -1
  6. package/dist/server/services/payment-gateways/PhonePeGateway.d.ts +2 -4
  7. package/dist/server/services/payment-gateways/PhonePeGateway.d.ts.map +1 -1
  8. package/dist/server/services/payment-gateways/PhonePeGateway.js +9 -15
  9. package/dist/server/services/payment-gateways/PhonePeGateway.js.map +1 -1
  10. package/dist/server/services/store/StoreConfigService.d.ts +4 -0
  11. package/dist/server/services/store/StoreConfigService.d.ts.map +1 -1
  12. package/dist/server/services/store/StoreConfigService.js +32 -0
  13. package/dist/server/services/store/StoreConfigService.js.map +1 -1
  14. package/dist/tsconfig.tsbuildinfo +1 -1
  15. package/dist/wwwroot/routes/pg-i/phone-pe/create/index.d.ts +2 -4
  16. package/dist/wwwroot/routes/pg-i/phone-pe/create/index.d.ts.map +1 -1
  17. package/dist/wwwroot/routes/pg-i/phone-pe/create/index.js +6 -74
  18. package/dist/wwwroot/routes/pg-i/phone-pe/create/index.js.map +1 -1
  19. package/package.json +1 -1
  20. package/src/server/seed/ui/seed-ui.ts +1 -1
  21. package/src/server/services/payment-gateways/Gateway.ts +30 -3
  22. package/src/server/services/payment-gateways/PhonePeGateway.ts +9 -10
  23. package/src/server/services/store/StoreConfigService.ts +23 -0
  24. package/src/wwwroot/routes/pg-i/phone-pe/create/index.tsx +6 -88
@@ -1,9 +1,7 @@
1
1
  import Page from "@entity-access/server-pages/dist/Page.js";
2
- import SocialMailContext from "../../../../../server/model/SocialMailContext.js";
3
- import StoreConfigService from "../../../../../server/services/store/StoreConfigService.js";
2
+ import PhonePeGateway from "../../../../../server/services/payment-gateways/PhonePeGateway.js";
4
3
  export default class extends Page {
5
- db: SocialMailContext;
6
- configService: StoreConfigService;
4
+ gateway: PhonePeGateway;
7
5
  run(): Promise<import("@entity-access/server-pages/dist/Content.js").Redirect>;
8
6
  }
9
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/wwwroot/routes/pg-i/phone-pe/create/index.tsx"],"names":[],"mappings":"AACA,OAAO,IAAI,MAAM,0CAA0C,CAAC;AAC5D,OAAO,iBAAiB,MAAM,kDAAkD,CAAC;AACjF,OAAO,kBAAkB,MAAM,4DAA4D,CAAC;AAK5F,MAAM,CAAC,OAAO,MAAO,SAAQ,IAAI;IAG7B,EAAE,EAAE,iBAAiB,CAAC;IAGtB,aAAa,EAAE,kBAAkB,CAAC;IAE5B,GAAG;CA2EZ"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/wwwroot/routes/pg-i/phone-pe/create/index.tsx"],"names":[],"mappings":"AACA,OAAO,IAAI,MAAM,0CAA0C,CAAC;AAC5D,OAAO,cAAc,MAAM,mEAAmE,CAAC;AAE/F,MAAM,CAAC,OAAO,MAAO,SAAQ,IAAI;IAG7B,OAAO,EAAE,cAAc,CAAC;IAElB,GAAG;CASZ"}
@@ -9,85 +9,17 @@ var __metadata = (this && this.__metadata) || function (k, v) {
9
9
  };
10
10
  import Inject from "@entity-access/entity-access/dist/di/di.js";
11
11
  import Page from "@entity-access/server-pages/dist/Page.js";
12
- import SocialMailContext from "../../../../../server/model/SocialMailContext.js";
13
- import StoreConfigService from "../../../../../server/services/store/StoreConfigService.js";
14
- import { randomUUID } from "crypto";
15
- import { createHash } from "node:crypto";
12
+ import PhonePeGateway from "../../../../../server/services/payment-gateways/PhonePeGateway.js";
16
13
  export default class default_1 extends Page {
17
14
  async run() {
18
- const [itemPriceID] = this.childPath;
15
+ const [itemID, currency] = this.childPath;
19
16
  const host = this.request.hostName;
20
- const q = this.db.storeItemPrices
21
- .where({ itemPriceID, host }, (p) => (x) => x.priceID === p.itemPriceID);
22
- // if (!this.sessionUser.isAdmin) {
23
- // q = q.where({ host }, (p) => (x) =>
24
- // x.storeItem.store.storeWebsites.some((w) => w.website.hosts.some((h) => h.host === p.host))
25
- // );
26
- // }
27
- const itemPrice = await q
28
- .include((x) => [x.storeItem.variantFor, x.storeItem.sizeFor])
29
- .firstOrFail();
30
- let name = "phone-pe";
31
- if (this.query.test) {
32
- name = "phone-pe-test";
33
- }
34
- const config = await this.configService.getConfigs(itemPrice.storeItem.storeID, name);
35
- const { merchantId, url, keyIndex, key } = config;
36
- const merchantTransactionId = randomUUID().replaceAll("-", "");
37
- const createRequest = {
38
- merchantId,
39
- merchantTransactionId,
40
- merchantUserId: randomUUID().replaceAll("-", ""),
41
- amount: itemPrice.amount * 100,
42
- callbackUrl: `https://${host}/callbacks/phonepe-callback/${merchantTransactionId}`,
43
- redirectUrl: `https://${host}/callbacks/phonepe-success/${merchantTransactionId}`,
44
- paymentInstrument: {
45
- type: "PAY_PAGE"
46
- }
47
- };
48
- const { request, verify } = signRequest(keyIndex, key, JSON.stringify(createRequest));
49
- const r = await fetch((url.endsWith("/") ? url.substring(1) : url) + "/pg/v1/pay", {
50
- method: "POST",
51
- headers: {
52
- "x-verify": verify,
53
- "content-type": "application/json"
54
- },
55
- body: JSON.stringify({ request })
56
- });
57
- if (r.status >= 300) {
58
- throw new Error(await r.text());
59
- }
60
- const text = await r.text();
61
- try {
62
- const rs = JSON.parse(text);
63
- if (rs.success) {
64
- const redirectUrl = rs?.data?.instrumentResponse?.redirectInfo?.url;
65
- if (redirectUrl) {
66
- return this.redirect(redirectUrl);
67
- }
68
- }
69
- throw new Error("Failed");
70
- }
71
- catch (error) {
72
- throw new Error(text);
73
- }
17
+ const pr = await this.gateway.createPaymentLink({ itemID, currency, host, testMode: this.query.test });
18
+ return this.redirect(pr.url);
74
19
  }
75
20
  }
76
21
  __decorate([
77
22
  Inject,
78
- __metadata("design:type", SocialMailContext)
79
- ], default_1.prototype, "db", void 0);
80
- __decorate([
81
- Inject,
82
- __metadata("design:type", StoreConfigService)
83
- ], default_1.prototype, "configService", void 0);
84
- function signRequest(id, salt, payload, path = "/pg/v1/pay") {
85
- const request = Buffer.from(payload, "utf-8").toString("base64");
86
- const signPayload = `${request}${path}${salt}`;
87
- const sha256 = createHash("sha256").update(signPayload).digest("hex");
88
- return {
89
- request,
90
- verify: `${sha256}###${id}`
91
- };
92
- }
23
+ __metadata("design:type", PhonePeGateway)
24
+ ], default_1.prototype, "gateway", void 0);
93
25
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../src/wwwroot/routes/pg-i/phone-pe/create/index.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../src/wwwroot/routes/pg-i/phone-pe/create/index.tsx"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,MAAM,MAAM,4CAA4C,CAAC;AAChE,OAAO,IAAI,MAAM,0CAA0C,CAAC;AAC5D,OAAO,cAAc,MAAM,mEAAmE,CAAC;AAE/F,MAAM,CAAC,OAAO,gBAAO,SAAQ,IAAI;IAK7B,KAAK,CAAC,GAAG;QAEL,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAE,GAAG,IAAI,CAAC,SAAkB,CAAC;QAEpD,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;QAEnC,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;QACvG,OAAO,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;IACjC,CAAC;CACJ;AAXG;IADC,MAAM;8BACE,cAAc;0CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@social-mail/social-mail-web-server",
3
- "version": "1.4.847",
3
+ "version": "1.4.849",
4
4
  "description": "## Phase 1",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -3,7 +3,7 @@ import semver from "semver";
3
3
 
4
4
  export default async function seedUI(config: DBConfig) {
5
5
 
6
- const version = "1.2.322";
6
+ const version = "1.2.323";
7
7
 
8
8
  const existing = await config.getValue(UIPackageConfig, false);
9
9
  if (existing) {
@@ -1,3 +1,7 @@
1
+ import Inject from "@entity-access/entity-access/dist/di/di.js";
2
+ import SocialMailContext from "../../model/SocialMailContext.js";
3
+ import StoreConfigService from "../store/StoreConfigService.js";
4
+
1
5
  export interface IPaymentGatewayCreateRequest {
2
6
  storeID: number;
3
7
  userID: string;
@@ -19,10 +23,33 @@ export interface IPaymentGatewayGetResponse {
19
23
  success: boolean;
20
24
  }
21
25
 
22
- export interface IPaymentGateway {
26
+ export abstract class PaymentGateway {
27
+
28
+ @Inject
29
+ configService: StoreConfigService;
30
+
31
+ @Inject
32
+ db: SocialMailContext;
33
+
34
+ async createPaymentLink({ itemID, host, testMode = false, currency = "USD"}) {
35
+ const { price, taxes } = await this.configService.getPrice(itemID, currency);
36
+ let total = price.amount;
37
+ for (const iterator of taxes) {
38
+ total += (price.amount*iterator.amount);
39
+ }
40
+
41
+ return this.create({
42
+ storeID: price.storeItem.storeID,
43
+ amount: total,
44
+ orderID: void 0,
45
+ userID: void 0,
46
+ host,
47
+ testMode
48
+ });
49
+ }
23
50
 
24
- create(req:IPaymentGatewayCreateRequest): Promise<IPaymentGatewayCreateResponse>;
51
+ abstract create(req:IPaymentGatewayCreateRequest): Promise<IPaymentGatewayCreateResponse>;
25
52
 
26
- get(req:IPaymentGatewayGetRequest): Promise<IPaymentGatewayGetResponse>;
53
+ abstract get(req:IPaymentGatewayGetRequest): Promise<IPaymentGatewayGetResponse>;
27
54
 
28
55
  }
@@ -1,7 +1,7 @@
1
1
  import Inject, { RegisterScoped } from "@entity-access/entity-access/dist/di/di.js";
2
- import { IPaymentGateway, IPaymentGatewayCreateRequest, IPaymentGatewayCreateResponse, IPaymentGatewayGetRequest, IPaymentGatewayGetResponse } from "./Gateway.js";
2
+ import { PaymentGateway, IPaymentGatewayCreateRequest, IPaymentGatewayCreateResponse, IPaymentGatewayGetRequest, IPaymentGatewayGetResponse } from "./Gateway.js";
3
3
  import StoreConfigService from "../store/StoreConfigService.js";
4
- import { createHash } from "node:crypto";
4
+ import { createHash, randomUUID } from "node:crypto";
5
5
 
6
6
  const signRequest = (id: any, salt: any, payload: string, path = "/pg/v1/pay"): { request: any; verify: any; } => {
7
7
  const request = Buffer.from(payload, "utf-8").toString("base64");
@@ -15,14 +15,13 @@ const signRequest = (id: any, salt: any, payload: string, path = "/pg/v1/pay"):
15
15
 
16
16
 
17
17
  @RegisterScoped
18
- export default class PhonePeGateway implements IPaymentGateway {
19
-
20
- @Inject
21
- configService: StoreConfigService;
18
+ export default class PhonePeGateway extends PaymentGateway {
22
19
 
23
20
  async create({ storeID, testMode, orderID, userID, amount, host }: IPaymentGatewayCreateRequest): Promise<IPaymentGatewayCreateResponse> {
24
21
 
25
- const config = await this.getConfig(storeID, testMode);
22
+ const name = testMode ? "phone-pe-test" : "phone-pe";
23
+
24
+ const config = await this.configService.getConfigs(storeID, name);
26
25
 
27
26
  const {
28
27
  merchantId,
@@ -31,12 +30,12 @@ export default class PhonePeGateway implements IPaymentGateway {
31
30
  key
32
31
  } = config;
33
32
 
34
- const merchantTransactionId = orderID;
33
+ const merchantTransactionId = orderID ?? randomUUID().replaceAll("-", "");
35
34
 
36
35
  const createRequest = {
37
36
  merchantId,
38
37
  merchantTransactionId,
39
- merchantUserId: userID,
38
+ merchantUserId: userID ?? randomUUID().replaceAll("-", ""),
40
39
  amount: amount * 100,
41
40
  callbackUrl: `https://${host}/callbacks/phonepe-callback/${merchantTransactionId}`,
42
41
  redirectUrl: `https://${host}/callbacks/phonepe-success/${merchantTransactionId}`,
@@ -64,7 +63,7 @@ export default class PhonePeGateway implements IPaymentGateway {
64
63
  if (rs.success) {
65
64
  const redirectUrl = rs?.data?.instrumentResponse?.redirectInfo?.url;
66
65
  if (redirectUrl) {
67
- return { url: redirectUrl };
66
+ return redirectUrl;
68
67
  }
69
68
  }
70
69
  throw new Error("Failed");
@@ -5,6 +5,7 @@ import SocialMailContext from "../../model/SocialMailContext.js";
5
5
  import EncryptionService from "../encryption/EncryptionService.js";
6
6
  import Sql from "@entity-access/entity-access/dist/sql/Sql.js";
7
7
  import { chainToCamel } from "../../../common/chainToCamel.js";
8
+ import DateTime from "@entity-access/entity-access/dist/types/DateTime.js";
8
9
 
9
10
  @RegisterSingleton
10
11
  export default class StoreConfigService {
@@ -38,4 +39,26 @@ export default class StoreConfigService {
38
39
  ).first();
39
40
  }
40
41
 
42
+ @cacheFor()
43
+ async getPrice(itemID, currency) {
44
+ using scope = ServiceProvider.createScope(this);
45
+ const db = scope.resolve(SocialMailContext);
46
+
47
+ const now = DateTime.now;
48
+
49
+ const q = db.storeItemPrices.where({ currency, now }, (p) => (x) =>
50
+ x.currency === p.currency
51
+ && x.startDate as any <= Sql.cast.asDateTime(p.now)
52
+ && (x.endDate === null || x.endDate as any > p.now)
53
+ );
54
+
55
+ const price = await q.where({ itemID }, (p) => (x) => x.storeItemID === p.itemID)
56
+ .include((x) => x.storeItem)
57
+ .first();
58
+
59
+ const taxes = await q.where({ itemID} , (p) => (x) => x.storeItem.taxItems.some((ti) => ti.storeItemID === p.itemID))
60
+ .toArray();
61
+
62
+ return { price, taxes };
63
+ }
41
64
  }
@@ -1,102 +1,20 @@
1
1
  import Inject from "@entity-access/entity-access/dist/di/di.js";
2
2
  import Page from "@entity-access/server-pages/dist/Page.js";
3
- import SocialMailContext from "../../../../../server/model/SocialMailContext.js";
4
- import StoreConfigService from "../../../../../server/services/store/StoreConfigService.js";
5
- import { randomUUID } from "crypto";
6
- import { globalEnv } from "../../../../../common/globalEnv.js";
7
- import { createHash } from "node:crypto";
3
+ import PhonePeGateway from "../../../../../server/services/payment-gateways/PhonePeGateway.js";
8
4
 
9
5
  export default class extends Page {
10
6
 
11
7
  @Inject
12
- db: SocialMailContext;
13
-
14
- @Inject
15
- configService: StoreConfigService;
8
+ gateway: PhonePeGateway;
16
9
 
17
10
  async run() {
18
11
 
19
- const [itemPriceID ] = this.childPath as any[];
20
- const host = this.request.hostName;
21
-
22
- const q = this.db.storeItemPrices
23
- .where({ itemPriceID, host }, (p) => (x) =>
24
- x.priceID === p.itemPriceID
25
- );
26
-
27
- // if (!this.sessionUser.isAdmin) {
28
- // q = q.where({ host }, (p) => (x) =>
29
- // x.storeItem.store.storeWebsites.some((w) => w.website.hosts.some((h) => h.host === p.host))
30
- // );
31
- // }
32
-
33
- const itemPrice = await q
34
- .include((x) => [x.storeItem.variantFor, x.storeItem.sizeFor])
35
- .firstOrFail();
36
-
37
- let name = "phone-pe";
38
- if (this.query.test) {
39
- name = "phone-pe-test";
40
- }
12
+ const [itemID, currency ] = this.childPath as any[];
41
13
 
42
- const config = await this.configService.getConfigs(itemPrice.storeItem.storeID, name);
43
-
44
- const {
45
- merchantId,
46
- url,
47
- keyIndex,
48
- key
49
- } = config;
50
-
51
- const merchantTransactionId = randomUUID().replaceAll("-", "");
52
-
53
- const createRequest = {
54
- merchantId,
55
- merchantTransactionId,
56
- merchantUserId: randomUUID().replaceAll("-", ""),
57
- amount: itemPrice.amount * 100,
58
- callbackUrl: `https://${host}/callbacks/phonepe-callback/${merchantTransactionId}`,
59
- redirectUrl: `https://${host}/callbacks/phonepe-success/${merchantTransactionId}`,
60
- paymentInstrument: {
61
- type: "PAY_PAGE"
62
- }
63
- };
64
-
65
- const { request, verify } = signRequest(keyIndex, key, JSON.stringify(createRequest));
14
+ const host = this.request.hostName;
66
15
 
67
- const r = await fetch((url.endsWith("/") ? url.substring(1) : url) + "/pg/v1/pay", {
68
- method: "POST",
69
- headers: {
70
- "x-verify": verify,
71
- "content-type": "application/json"
72
- },
73
- body: JSON.stringify({ request })
74
- });
75
- if(r.status >= 300) {
76
- throw new Error(await r.text());
77
- }
78
- const text = await r.text();
79
- try {
80
- const rs = JSON.parse(text);
81
- if (rs.success) {
82
- const redirectUrl = rs?.data?.instrumentResponse?.redirectInfo?.url;
83
- if (redirectUrl) {
84
- return this.redirect(redirectUrl);
85
- }
86
- }
87
- throw new Error("Failed");
88
- } catch (error) {
89
- throw new Error(text);
90
- }
16
+ const pr = await this.gateway.createPaymentLink({ itemID, currency, host, testMode: this.query.test });
17
+ return this.redirect(pr.url);
91
18
  }
92
19
  }
93
20
 
94
- function signRequest(id: any, salt: any, payload: string, path = "/pg/v1/pay"): { request: any; verify: any; } {
95
- const request = Buffer.from(payload, "utf-8").toString("base64");
96
- const signPayload = `${request}${path}${salt}`;
97
- const sha256 = createHash("sha256").update(signPayload).digest("hex");
98
- return {
99
- request,
100
- verify: `${sha256}###${id}`
101
- };
102
- }