Skip to content

Commit 739694a

Browse files
authored
feat: add Stripe payment integration with probability-based failure scenarios and pytest tests (#20)
1 parent b60f8a4 commit 739694a

File tree

12 files changed

+1412
-16
lines changed

12 files changed

+1412
-16
lines changed
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
name: Cycle Payment Scenarios
2+
3+
on:
4+
schedule:
5+
# Run every 3 hours
6+
- cron: '0 */3 * * *'
7+
workflow_dispatch: # Allow manual trigger
8+
9+
jobs:
10+
cycle-scenario:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- name: Reset all scenarios
14+
run: |
15+
echo "Resetting all payment scenarios..."
16+
curl -X POST "${{ secrets.SCENARIO_SERVICE_URL }}/scenario-runner/api/payment-scenarios/reset"
17+
sleep 2
18+
19+
- name: Select random scenario
20+
id: random
21+
run: |
22+
# Generate random number 1-3
23+
SCENARIO=$((RANDOM % 3 + 1))
24+
echo "Selected scenario: $SCENARIO"
25+
echo "scenario=$SCENARIO" >> $GITHUB_OUTPUT
26+
27+
- name: Enable Gateway Timeout (Scenario 1)
28+
if: steps.random.outputs.scenario == '1'
29+
run: |
30+
echo "Enabling Gateway Timeout scenario (15% probability, 15s delay)"
31+
curl -X POST "${{ secrets.SCENARIO_SERVICE_URL }}/scenario-runner/api/payment-scenarios/gateway-timeout?enabled=true&probability=15.0&delay=15"
32+
33+
- name: Enable Card Decline (Scenario 2)
34+
if: steps.random.outputs.scenario == '2'
35+
run: |
36+
echo "Enabling Card Decline scenario (20% probability)"
37+
curl -X POST "${{ secrets.SCENARIO_SERVICE_URL }}/scenario-runner/api/payment-scenarios/card-decline?enabled=true&probability=20.0"
38+
39+
- name: Enable Stolen Card (Scenario 3)
40+
if: steps.random.outputs.scenario == '3'
41+
run: |
42+
echo "Enabling Stolen Card scenario (10% probability)"
43+
curl -X POST "${{ secrets.SCENARIO_SERVICE_URL }}/scenario-runner/api/payment-scenarios/stolen-card?enabled=true&probability=10.0"
44+
45+
- name: Verify scenario configuration
46+
run: |
47+
echo "Current scenario configuration:"
48+
curl "${{ secrets.SCENARIO_SERVICE_URL }}/scenario-runner/api/payment-scenarios"

bill_pay/Dockerfile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,13 @@ ENV NEW_RELIC_LICENSE_KEY=$NEW_RELIC_LICENSE_KEY
3838

3939
ENV NEW_RELIC_DISTRIBUTED_TRACING_ENABLED=true
4040

41+
# Stripe API keys
42+
ARG STRIPE_SECRET_KEY
43+
ENV STRIPE_SECRET_KEY=$STRIPE_SECRET_KEY
44+
45+
ARG STRIPE_PUBLISHABLE_KEY
46+
ENV STRIPE_PUBLISHABLE_KEY=$STRIPE_PUBLISHABLE_KEY
47+
4148
# ENV NEW_RELIC_CONFIG_FILE="newrelic.ini"
4249

4350
# Copy the requirements file and install dependencies

bill_pay/README.md

Lines changed: 87 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,13 @@ This service is a core component of the **Relibank** FinServ application. Its pr
88

99
* **RESTful API**: Exposes a RESTful API for handling one-time, recurring, and cancellation requests.
1010

11+
* **Stripe Integration**: Processes card payments via Stripe API (test mode only for development).
12+
13+
* **Payment Method Storage**: Stores and manages customer payment methods (cards) in Stripe.
14+
1115
* **Pydantic Validation**: Validates all incoming API requests to ensure data integrity.
1216

13-
* **Kafka Producer**: Publishes payment-related events to dedicated Kafka topics: `bill_payments`, `recurring_payments`, and `payment_cancellations`.
17+
* **Kafka Producer**: Publishes payment-related events to dedicated Kafka topics: `bill_payments`, `recurring_payments`, `payment_cancellations`, and `card_payments`.
1418

1519
* **Service-to-Service Communication**: Makes a synchronous API call to the `transaction-service` to check for the existence of a `billId` before processing a payment or cancellation. This ensures data consistency and prevents duplicate transactions.
1620

@@ -22,28 +26,104 @@ This service is a core component of the **Relibank** FinServ application. Its pr
2226

2327
The service exposes the following API endpoints, which are designed to be consumed by the customer portal or other upstream services.
2428

29+
#### Account Transfer Payments
2530
| Endpoint | Method | Description | Request Body |
2631
| :--- | :--- | :--- | :--- |
2732
| `/pay` | `POST` | Initiates a one-time bill payment. | `fromAccountId`, `toAccountId`, `amount`, `currency`, `billId` |
2833
| `/recurring` | `POST` | Schedules a recurring bill payment. | `fromAccountId`, `toAccountId`, `amount`, `currency`, `billId`, `frequency`, `startDate` |
2934
| `/cancel/{bill_id}` | `POST` | Cancels a pending or recurring payment after verifying it exists. | `user_id` |
35+
36+
#### Card Payments (Stripe)
37+
| Endpoint | Method | Description | Request Body |
38+
| :--- | :--- | :--- | :--- |
39+
| `/card-payment` | `POST` | Process a card payment via Stripe. | `billId`, `amount`, `currency`, `cardNumber`, `expMonth`, `expYear`, `cvc`, `saveCard`, `customerId` |
40+
| `/payment-method` | `POST` | Save a payment method (card) for future use. | `cardNumber`, `expMonth`, `expYear`, `cvc`, `customerId`, `customerEmail` |
41+
| `/payment-methods/{customer_id}` | `GET` | List all saved payment methods for a customer. | None |
42+
43+
#### Health Check
44+
| Endpoint | Method | Description | Request Body |
45+
| :--- | :--- | :--- | :--- |
3046
| `/health` | `GET` | A health check endpoint that returns a status of `healthy`. | None |
3147

3248
---
3349

50+
### 🔧 Stripe Configuration
51+
52+
To enable card payment functionality, you need to configure Stripe API keys.
53+
54+
1. **Get Stripe Test Keys**:
55+
- Sign up at https://stripe.com
56+
- Get test API keys from https://dashboard.stripe.com/test/apikeys
57+
- Copy your `sk_test_*` (secret key) and `pk_test_*` (publishable key)
58+
59+
2. **Add to skaffold.env**:
60+
```bash
61+
STRIPE_SECRET_KEY=sk_test_your_secret_key_here
62+
STRIPE_PUBLISHABLE_KEY=pk_test_your_publishable_key_here
63+
```
64+
65+
3. **Keys Flow**: `skaffold.env``skaffold.yaml``Dockerfile` → container environment
66+
67+
4. **Test Cards**: Use Stripe test cards for development:
68+
- `4242424242424242` - Visa (succeeds)
69+
- `4000000000000002` - Visa (declined)
70+
- `4000000000009995` - Visa (insufficient funds)
71+
- Any future expiration, any CVC, any ZIP
72+
73+
**Note**: If Stripe keys are not configured, card payment endpoints will return 503 errors. Account transfer payments will continue to work normally.
74+
75+
---
76+
77+
### 🎭 Demo Scenarios
78+
79+
The card payment endpoint integrates with the scenario service to support runtime-toggleable failure scenarios for demonstrations:
80+
81+
#### Available Scenarios
82+
83+
1. **Card Decline**: Payments matching a specific amount will be declined with "insufficient funds"
84+
- Default decline amount: $999.99
85+
- Configurable via scenario service API
86+
87+
2. **Gateway Timeout**: Simulate payment gateway delays and timeouts
88+
- Default: Disabled
89+
- Configurable delay: 1-60 seconds
90+
- Enables realistic timeout behavior for demos
91+
92+
#### Managing Scenarios
93+
94+
Control scenarios via the scenario service API (port 8000):
95+
96+
```bash
97+
# Get current scenario configuration
98+
curl http://localhost:8000/scenario-runner/api/payment-scenarios
99+
100+
# Enable gateway timeout with 15 second delay
101+
curl -X POST "http://localhost:8000/scenario-runner/api/payment-scenarios/gateway-timeout?enabled=true&delay=15"
102+
103+
# Set decline amount to $50.00
104+
curl -X POST "http://localhost:8000/scenario-runner/api/payment-scenarios/decline-amount?amount=50.00"
105+
106+
# Reset all scenarios to defaults
107+
curl -X POST http://localhost:8000/scenario-runner/api/payment-scenarios/reset
108+
```
109+
110+
These scenarios are also available in the Postman collection under "scenario service".
111+
112+
---
113+
34114
### ⚙️ How to Run
35115

36-
This service is designed to be run using Docker Compose as part of the larger **Relibank** application stack.
116+
This service is designed to be run using Skaffold as part of the larger **Relibank** application stack.
37117

38-
1. **Ensure Docker Compose is Installed**: Make sure you have Docker and Docker Compose installed and running on your system.
118+
1. **Configure Environment**: Ensure `skaffold.env` contains required variables including Stripe keys (optional).
39119

40-
2. **Navigate to the Root Directory**: Open a terminal and navigate to the root directory of the `relibank` repository, where the `docker-compose.yml` file is located.
120+
2. **Navigate to Root Directory**: Open a terminal and navigate to the root directory of the `relibank` repository.
41121

42-
3. **Start the Stack**: Run the following command to build the service images and start all containers. The `--build` flag is crucial for applying any code or dependency changes.
122+
3. **Start the Stack**: Run the following command to build and deploy all services:
43123

44124
```bash
45-
docker compose up --build
125+
skaffold dev
46126
```
47127

48-
This command will start the `mssql` and `kafka` containers first, wait for them to become healthy, and then start the `bill-pay` service.
128+
This command will build all services, deploy to Kubernetes, and start port forwarding.
49129

0 commit comments

Comments
 (0)