Skip to content

feat(subscriptions): Invoice record back workflow#9529

Merged
Gnanasundari24 merged 195 commits intomainfrom
invoice-record-back-workflow
Oct 3, 2025
Merged

feat(subscriptions): Invoice record back workflow#9529
Gnanasundari24 merged 195 commits intomainfrom
invoice-record-back-workflow

Conversation

@Sarthak1799
Copy link
Contributor

@Sarthak1799 Sarthak1799 commented Sep 23, 2025

Type of Change

  • Bugfix
  • New feature
  • Enhancement
  • Refactoring
  • Dependency updates
  • Documentation
  • CI/CD

Description

This pull request introduces a comprehensive set of changes to add invoice management capabilities to the codebase. The changes include new data models and enums for invoices, database schema and query support, and integration with connectors and APIs for invoice-related workflows.

Invoice Data Model and Enums

  • Added the InvoiceStatus enum to represent the various states an invoice can be in, such as InvoiceCreated, PaymentPending, PaymentSucceeded, etc. (crates/common_enums/src/connector_enums.rs)
  • Introduced the InvoiceRecordBackTrackingData struct for tracking invoice-related process data, along with a constructor. (crates/api_models/src/process_tracker/invoice_record_back.rs)
  • Created a new InvoiceId type and implemented associated methods and traits, including event metric integration. (crates/common_utils/src/id_type/invoice.rs)
  • Registered the new InvoiceId in the global ID types and exposed it for use. (crates/common_utils/src/id_type.rs) [1] [2]
  • Added Invoice to the ApiEventsType enum for event categorization. (crates/common_utils/src/events.rs)
  • Extended the ProcessTrackerRunner enum to include InvoiceRecordBackflow. (crates/common_enums/src/enums.rs)

Database Schema and Models

  • Added a new invoice table to the Diesel ORM schema (both v1 and v2), including all necessary fields and indices. (crates/diesel_models/src/schema.rs, crates/diesel_models/src/schema_v2.rs) [1] [2] [3] [4]
  • Implemented the Invoice, InvoiceNew, and InvoiceUpdate structs for ORM mapping, along with constructors and update methods. (crates/diesel_models/src/invoice.rs)
  • Added query support for inserting, finding, and updating invoices in the database. (crates/diesel_models/src/query/invoice.rs)
  • Registered the new invoice module in the Diesel models and query modules. (crates/diesel_models/src/lib.rs, crates/diesel_models/src/query.rs) [1] [2]

Connector and API Integration

  • Added support for the invoice record backflow in the Chargebee and Recurly connectors, including trait implementations and integration with request/response types. (crates/hyperswitch_connectors/src/connectors/chargebee.rs, crates/hyperswitch_connectors/src/connectors/recurly.rs) [1] [2] [3] [4]
  • Updated the default connector implementations to support the new invoice record backflow and related API flows. (crates/hyperswitch_connectors/src/default_implementations.rs) [1] [2] [3] [4]

API Models

  • Added a new module for invoice_record_back in the process tracker API models. (crates/api_models/src/process_tracker.rs)

Summary of Most Important Changes:

Invoice Data Model and Enums

  • Introduced the InvoiceStatus enum and the InvoiceRecordBackTrackingData struct for invoice state tracking and process workflows. [1] [2]
  • Added a new InvoiceId type with associated methods and event metric integration. [1] [2] [3] [4]
  • Extended process tracker and event enums for invoice support. [1] [2]

Database Schema and Models

  • Created a new invoice table in the Diesel schema, and implemented corresponding ORM structs and query methods for invoice creation, lookup, and updates. [1] [2] [3] [4] [5] [6] [7] [8]

Connector and API Integration

  • Added invoice record backflow support to Chargebee and Recurly connectors, and updated default connector implementations for new invoice-related flows. [1] [2] [3] [4] [5] [6] [7] [8]

API Models

  • Registered a new invoice_record_back module in the process tracker API models.

Additional Changes

  • This PR modifies the API contract
  • This PR modifies the database schema
  • This PR modifies application configuration/environment variables

Motivation and Context

How did you test it?

  1. Create+Confirm subscription
curl --location 'http://localhost:8080/subscriptions' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'X-Profile-Id: pro_2WzEeiNyj8fSCObXqo36' \
--header 'api-key: dev_Ske75Nx2J7qtHsP8cc7pFx5k4dccYBedM6UAExaLOdHCkji3uVWSqfmZ0Qz0Tnyj' \
--data '{
    "item_price_id": "cbdemo_enterprise-suite-monthly",
    "customer_id": "cus_27J5gnsyKB4XrzyIxeoS",
    "description": "Hello this is description",
    "merchant_reference_id": "mer_ref_1759334677",
    "shipping": {
        "address": {
            "state": "zsaasdas",
            "city": "Banglore",
            "country": "US",
            "line1": "sdsdfsdf",
            "line2": "hsgdbhd",
            "line3": "alsksoe",
            "zip": "571201",
            "first_name": "joseph",
            "last_name": "doe"
        },
        "phone": {
            "number": "123456789",
            "country_code": "+1"
        }
    },
    "billing": {
        "address": {
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "city": "San Fransico",
            "state": "California",
            "zip": "94122",
            "country": "US",
            "first_name": "joseph",
            "last_name": "Doe"
        },
        "phone": {
            "number": "123456789",
            "country_code": "+1"
        }
    },
    "payment_details": {
        "payment_method": "card",
        "payment_method_type": "credit",
        "payment_method_data": {
            "card": {
                "card_number": "4111111111111111",
                "card_exp_month": "03",
                "card_exp_year": "2030",
                "card_holder_name": "CLBRW dffdg",
                "card_cvc": "737"
            }
        },
        "authentication_type": "no_three_ds",
        "setup_future_usage": "off_session",
        "capture_method": "automatic",
        "return_url": "https://google.com",
        "customer_acceptance": {
            "acceptance_type": "online",
            "accepted_at": "1963-05-03T04:07:52.723Z",
            "online": {
                "ip_address": "127.0.0.1",
                "user_agent": "amet irure esse"
            }
        }
    }
}'

Response -

{"id":"sub_qHATQ50oyNXU88ATREqE","merchant_reference_id":"mer_ref_1759334677","status":"active","plan_id":null,"price_id":null,"coupon":null,"profile_id":"pro_2WzEeiNyj8fSCObXqo36","payment":{"payment_id":"pay_i25XfiRs8BZhuVuKIMeZ","status":"succeeded","amount":14100,"currency":"INR","connector":"stripe","payment_method_id":"pm_MjezVPJ1fyh70zER6aNW","payment_experience":null,"error_code":null,"error_message":null,"payment_method_type":"credit"},"customer_id":"cus_27J5gnsyKB4XrzyIxeoS","invoice":{"id":"invoice_2xFn2gjrxUshLw0A3FwG","subscription_id":"sub_qHATQ50oyNXU88ATREqE","merchant_id":"merchant_1758626894","profile_id":"pro_2WzEeiNyj8fSCObXqo36","merchant_connector_id":"mca_eN6JxSK2NkuT0wSYAH5s","payment_intent_id":"pay_i25XfiRs8BZhuVuKIMeZ","payment_method_id":null,"customer_id":"cus_27J5gnsyKB4XrzyIxeoS","amount":14100,"currency":"INR","status":"payment_pending"},"billing_processor_subscription_id":"sub_qHATQ50oyNXU88ATREqE"}
image image image

Checklist

  • I formatted the code cargo +nightly fmt --all
  • I addressed lints thrown by cargo clippy
  • I reviewed the submitted code
  • I added unit tests for my changes where possible

prajjwalkumar17 and others added 30 commits August 25, 2025 19:14
jagan-jaya
jagan-jaya previously approved these changes Oct 3, 2025
jagan-jaya
jagan-jaya previously approved these changes Oct 3, 2025
@@ -0,0 +1,452 @@
#[cfg(feature = "v1")]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why feature flag is not removed here? And in other places too in this module?

Copy link
Contributor Author

@Sarthak1799 Sarthak1799 Oct 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the subscription core module itself is gated under v1 as it has DB calls where the DB interface differs between v1 and v2. For example, customer DB interface has different implementation for both versions, we are using the v1 implementation.
We would have to replicate the functions where different DB interfaces are involved. hence had kept the feature flag.

storage::invoice_sync::InvoiceSyncPaymentStatus::PaymentProcessing => {
let db = &*self.state.store;
let connector = self.tracking_data.connector_name.to_string().clone();
let is_last_retry = retry_subscription_invoice_sync_task(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

transition_workflow_state function is like a control plane for controlling the job related action for the workflow in every branch, if a helper function is created to handle job then lets have all logic related to job handling inside it or job related functionality lets have here itself, i.e move is_last_retry logic inside retry_subscription_invoice_sync_task or move job related logic from retry_subscription_invoice_sync_task to here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

have moved all the logic to retry_subscription_invoice_sync_task
We did not need the last retry part as the retry_subscription_invoice_sync_task function marks the appropriate status for the job.

jarnura
jarnura previously approved these changes Oct 3, 2025
@Gnanasundari24 Gnanasundari24 added this pull request to the merge queue Oct 3, 2025
Merged via the queue into main with commit 0a35c61 Oct 3, 2025
21 of 25 checks passed
@Gnanasundari24 Gnanasundari24 deleted the invoice-record-back-workflow branch October 3, 2025 19:49
pixincreate added a commit that referenced this pull request Oct 7, 2025
…esouro-googlepay

* 'main' of github.com:juspay/hyperswitch:
  feat(connector): [tesouro] apple pay (#9648)
  fix(payments): update error handling for payment void v2 (#9595)
  fix(connectors): [Nexixpay] MIT & order_id fix (#9644)
  chore(version): 2025.10.07.0
  fix(database): percent-encode spaces in Postgres connection URI (#9685)
  chore(version): 2025.10.06.0
  feat(subscriptions): Invoice record back workflow (#9529)
  feat: Implement subscriptions workflow and incoming webhook support (#9400)
  Feat(Customer): Added search Feature to the Customer Page (#9619)
  chore(version): 2025.10.02.0
  feat(subscription): Add support to call payments microservice from subscription service via payments API client (#9590)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Invoice sync workflow to check psync status and call record back on successful payment

6 participants