Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,24 @@ follows [Semantic Versioning](https://semver.org/).

_Bounded-context implementation (iam, billing, workspace, discovery, gateway) in progress._

### Fixed (Billing guide matches the current deployment — `bugfix/docs-billing-current-deploy`)

- **`docs/BILLING.md` described an old AWS layout**, with CloudFront, an ALB and the `app.tamci.app`
domain. The MVP now runs on `reqsai.tech`, where Caddy serves the web and proxies `/api/*` from one
origin, so the Stripe webhook is `https://reqsai.tech/api/billing/webhooks/stripe`.
- **The guide now says where the MVP host keeps the Stripe settings:** the infra vault and
`app_api_settings`.
- **The Stripe prices to create are USD 49 (Pro) and USD 149 (Enterprise)**, the amounts the app
displays (`BILLING_*_AMOUNT_CENTS`). The guide said USD 29 and USD 99.

### Fixed (Jira OAuth callback in the dev profile — `bugfix/jira-dev-callback-url`)

- **The `dev` profile pointed the Atlassian callback at `/integrations/jira/callback`, a route the web
does not have.** The web callback lives at `/settings/integrations/jira/callback`, which is what the
base config, `.env.example` and `docs/JIRA_INTEGRATION.md` use. A local "Conectar con Atlassian" without
`JIRA_OAUTH_CALLBACK_URL` sent Atlassian a redirect that did not match the registered one. Production
was not affected: it derives the URL from `FRONTEND_URL`.

### Added (Story approval — `feature/discovery-story-approval`)

- **A story can now be approved, rejected or sent back to draft.** Until now every story stayed in
Expand Down
17 changes: 11 additions & 6 deletions docs/BILLING.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,12 @@ Create the plans in Stripe to map them to your system:
2. Create **"ReqsAI Pro"**:
- Pricing: **Recurring**
- Interval: **Monthly**
- Amount: **USD 29.00**
- Amount: **USD 49.00**
- Save the product and copy the **Price ID** (looks like `price_1AbPro...`).
3. Create **"ReqsAI Enterprise"**:
- Pricing: **Recurring**
- Interval: **Monthly**
- Amount: **USD 99.00**
- Amount: **USD 149.00**
- Save and copy the **Price ID** (looks like `price_1AbEnt...`).
4. Set these in your `.env` file:
```env
Expand Down Expand Up @@ -108,17 +108,22 @@ For university presentations, demo environments, or staging deployments, **you s
Since your deployed application has a public domain name, **you do not need the Stripe CLI (`stripe listen`) running on your server**. Stripe can send the webhook events directly to your public URL:

1. In the Stripe Dashboard (with **Test Mode** turned ON), go to **Developers** ▸ **Webhooks** and click **Add endpoint**.
2. Set the **Endpoint URL** to your deployed backend domain:
2. Set the **Endpoint URL** to the public domain of the app. The web and the API share one origin
(Caddy proxies `/api/*` to the API on the MVP host), so the webhook lives under the same domain:
```text
https://your-api-domain.com/api/billing/webhooks/stripe
https://reqsai.tech/api/billing/webhooks/stripe
```
3. Click **Select events** and subscribe to:
* `checkout.session.completed`
* `customer.subscription.deleted`
* `invoice.payment_failed`
4. Click **Add endpoint** to save.
5. Under the endpoint details page, click **Reveal** under the **Signing secret** section.
6. Copy this secret (starts with `whsec_...`) and configure the `STRIPE_WEBHOOK_SECRET` environment variable on your deployed server (e.g., in AWS, Render, or ECS).
6. Copy this secret (starts with `whsec_...`) into the deployment's secrets. On the MVP host it is
`vault_stripe_webhook_secret` in the ansible vault of
[reqsai-infra](https://github.com/Kntro-Soft/reqsai-infra), next to `vault_stripe_api_key`. The
provider and the price ids go in the host's `app_api_settings` (`BILLING_PAYMENT_PROVIDER: stripe`,
`BILLING_*_STRIPE_PRICE_ID`). Redeploy so the API picks them up.

---

Expand All @@ -132,7 +137,7 @@ When deploying to production, apply the following changes:
2. **Products & Prices**: Create the production products and prices in the live dashboard catalog and update `BILLING_*_STRIPE_PRICE_ID` environment variables.
3. **Webhook Registration**:
- Go to **Developers** ▸ **Webhooks** ▸ **Add endpoint**.
- Set the URL to your live API endpoint: `https://your-api-domain.com/api/billing/webhooks/stripe`.
- Set the URL to `https://reqsai.tech/api/billing/webhooks/stripe` (same origin as the web app).
- Subscribe to these events:
* `checkout.session.completed` (handles purchase / upgrade activation).
* `customer.subscription.deleted` (handles cancellation/lapse).
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/application-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ reqsai:
oauth:
client-id: ${JIRA_OAUTH_CLIENT_ID:dev-client-id}
client-secret: ${JIRA_OAUTH_CLIENT_SECRET:dev-client-secret}
redirect-uri: ${JIRA_OAUTH_CALLBACK_URL:http://localhost:4200/integrations/jira/callback}
redirect-uri: ${JIRA_OAUTH_CALLBACK_URL:http://localhost:4200/settings/integrations/jira/callback}
state-secret: ${JIRA_OAUTH_STATE_SECRET:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef}

logging:
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ reqsai:
# ISO-4217 display currency.
currency: ${BILLING_CURRENCY:USD}
# Per-plan DISPLAY pricing (minor units / cents) + the Stripe Price id actually charged.
# Defined prices: PRO USD 29.00/mo, ENTERPRISE USD 99.00/mo (FREE is $0, provisioned on signup).
# Defined prices: PRO USD 49.00/mo, ENTERPRISE USD 149.00/mo (FREE is $0, provisioned on signup).
# NOTE: amount-cents is display only; the CHARGED amount is the Stripe Price object, so the
# recurring Price you create in Stripe MUST match these amounts (keep the web plan catalog in sync).
plans:
Expand Down
Loading