Skip to content

Commit beba0bd

Browse files
authored
Merge pull request #224 from codeableorg/payments
Integrate Culqi payment gateway in Checkout component
2 parents aa5d674 + f70f43f commit beba0bd

File tree

23 files changed

+331
-38
lines changed

23 files changed

+331
-38
lines changed

.env.example

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,7 @@ DB_PASSWORD=your_db_password
1010

1111
# Admin Database (for database creation/deletion)
1212
ADMIN_DB_NAME=postgres
13+
14+
# Culqui Keys
15+
CULQI_PRIVATE_KEY="sk_test_xxx"
16+
VITE_CULQI_PUBLIC_KEY="pk_test_xxx"

.env.test

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
11
DATABASE_URL="postgresql://diego@localhost:5432/fullstock_test?schema=public"
22

33
# Admin Database (for database creation/deletion)
4-
ADMIN_DB_NAME=postgres
4+
ADMIN_DB_NAME=postgres
5+
6+
# Cloud Storage base url
7+
CS_BASE_URL="https://fullstock-images.s3.us-east-2.amazonaws.com"
8+
9+
CULQI_PRIVATE_KEY="sk_test_EC8oOLd3ZiCTKqjN"
10+
VITE_CULQI_PUBLIC_KEY="pk_test_Ws4NXfH95QXlZgaz"

.github/workflows/tests.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,11 @@ jobs:
6161
e2e-test:
6262
runs-on: ubuntu-latest
6363
needs: [test]
64+
env:
65+
CS_BASE_URL: "https://fullstock-images.s3.us-east-2.amazonaws.com"
66+
CULQI_PRIVATE_KEY: "sk_test_EC8oOLd3ZiCTKqjN"
67+
VITE_CULQI_PUBLIC_KEY: "pk_test_Ws4NXfH95QXlZgaz"
68+
DATABASE_URL: "postgresql://diego@localhost:5432/fullstock_test?schema=public"
6469
services:
6570
postgres:
6671
image: postgres:15

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
"prisma:studio": "prisma studio",
2020
"prisma:seed": "prisma db seed",
2121
"test:prisma:migrate:deploy": "dotenv -e .env.test -- prisma migrate deploy",
22+
"test:prisma:migrate:reset": "dotenv -e .env.test -- prisma migrate reset",
2223
"test:e2e": "playwright test",
2324
"test:prisma:seed": "dotenv -e .env.test prisma db seed"
2425
},
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
-- AlterTable
2+
ALTER TABLE "orders" ADD COLUMN "payment_id" TEXT;

prisma/schema.prisma

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ model Order {
103103
userId Int @map("user_id")
104104
totalAmount Decimal @map("total_amount") @db.Decimal(10, 2)
105105
email String
106+
paymentId String? @map("payment_id")
106107
firstName String @map("first_name")
107108
lastName String @map("last_name")
108109
company String?

public/.well-known/appspecific/com.chrome.devtools.json

Whitespace-only changes.

src/e2e/guest-create-order.spec.ts

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
// import { createOrderFormData } from "@/lib/utils.tests";
22
import { expect, test } from "@playwright/test";
33

4-
import { baseUrl, cleanDatabase, createOrderFormData } from "./utils-tests-e2e";
4+
import {
5+
baseUrl,
6+
cleanDatabase,
7+
createOrderFormData,
8+
creditCards,
9+
} from "./utils-tests-e2e";
510

611
export type OrderFormData = Record<string, string>;
712

@@ -33,9 +38,43 @@ test.describe("Guest", () => {
3338

3439
await page.getByRole("button", { name: "Confirmar Orden" }).click();
3540

41+
const checkoutFrame = page.locator('iframe[name="checkout_frame"]');
42+
await expect(checkoutFrame).toBeVisible({ timeout: 10000 });
43+
44+
const validCard = creditCards.valid;
45+
46+
await checkoutFrame
47+
.contentFrame()
48+
.getByRole("textbox", { name: "#### #### #### ####" })
49+
.fill(validCard.number);
50+
3651
await expect(
37-
page.getByText("¡Muchas gracias por tu compra!")
52+
checkoutFrame.contentFrame().getByRole("img", { name: "Culqi icon" })
3853
).toBeVisible();
54+
55+
await checkoutFrame
56+
.contentFrame()
57+
.getByRole("textbox", { name: "MM/AA" })
58+
.fill(validCard.exp);
59+
60+
await checkoutFrame
61+
.contentFrame()
62+
.getByRole("textbox", { name: "CVV" })
63+
.fill(validCard.cvv);
64+
65+
await checkoutFrame
66+
.contentFrame()
67+
.getByRole("textbox", { name: "[email protected]" })
68+
.fill(orderForm["Correo electrónico"]);
69+
70+
await checkoutFrame
71+
.contentFrame()
72+
.getByRole("button", { name: "Pagar S/" })
73+
.click();
74+
75+
await expect(page.getByText("¡Muchas gracias por tu compra!")).toBeVisible({
76+
timeout: 10000,
77+
});
3978
await expect(page.getByTestId("orderId")).toBeVisible();
4079
});
4180
});

src/e2e/user-create-order.spec.ts

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { prisma } from "@/db/prisma";
44
import { hashPassword } from "@/lib/security";
55
import type { CreateUserDTO } from "@/models/user.model";
66

7-
import { baseUrl, cleanDatabase } from "./utils-tests-e2e";
7+
import { baseUrl, cleanDatabase, creditCards } from "./utils-tests-e2e";
88

99
test.beforeEach(async () => {
1010
await cleanDatabase();
@@ -76,9 +76,43 @@ test.describe("User", () => {
7676

7777
await page.getByRole("button", { name: "Confirmar Orden" }).click();
7878

79+
const checkoutFrame = page.locator('iframe[name="checkout_frame"]');
80+
await expect(checkoutFrame).toBeVisible({ timeout: 10000 });
81+
82+
const validCard = creditCards.valid;
83+
84+
await checkoutFrame
85+
.contentFrame()
86+
.getByRole("textbox", { name: "#### #### #### ####" })
87+
.fill(validCard.number);
88+
7989
await expect(
80-
page.getByText("¡Muchas gracias por tu compra!")
90+
checkoutFrame.contentFrame().getByRole("img", { name: "Culqi icon" })
8191
).toBeVisible();
92+
93+
await checkoutFrame
94+
.contentFrame()
95+
.getByRole("textbox", { name: "MM/AA" })
96+
.fill(validCard.exp);
97+
98+
await checkoutFrame
99+
.contentFrame()
100+
.getByRole("textbox", { name: "CVV" })
101+
.fill(validCard.cvv);
102+
103+
await checkoutFrame
104+
.contentFrame()
105+
.getByRole("textbox", { name: "[email protected]" })
106+
.fill(loginForm["Correo electrónico"]);
107+
108+
await checkoutFrame
109+
.contentFrame()
110+
.getByRole("button", { name: "Pagar S/" })
111+
.click();
112+
113+
await expect(page.getByText("¡Muchas gracias por tu compra!")).toBeVisible({
114+
timeout: 10000,
115+
});
82116
await expect(page.getByTestId("orderId")).toBeVisible();
83117
});
84118
});

src/e2e/utils-tests-e2e.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,19 @@ export const createOrderFormData = (
1919
...overrides,
2020
});
2121

22+
export const creditCards = {
23+
valid: {
24+
number: "4111 1111 1111 1111",
25+
exp: "12/30",
26+
cvv: "123",
27+
},
28+
declined: {
29+
number: "4000 0200 0000 0000",
30+
exp: "12/30",
31+
cvv: "354",
32+
},
33+
};
34+
2235
export async function cleanDatabase() {
2336
await prisma.order.deleteMany();
2437
await prisma.cart.deleteMany();

0 commit comments

Comments
 (0)