### Node.js Client Initialization for Firestore LiqPay Payments Source: https://context7.com/summerhammer/firestore-liqpay-payments/llms.txt Demonstrates how to initialize the Firestore LiqPay client in a Node.js environment using the `firestore-liqpay-node-client` library. It shows examples of using default configurations and custom configurations, including dynamic path substitutions for Firestore collections. ```typescript import { FirestoreLiqPayClient } from "firestore-liqpay-node-client"; import * as admin from "firebase-admin"; // Initialize Firebase Admin SDK first admin.initializeApp(); // Option 1: Use default configuration (invoices, checkout-sessions) const client = FirestoreLiqPayClient.createDefault(); // Option 2: Custom configuration with token substitution in collection paths const customClient = new FirestoreLiqPayClient({ payments: { invoicesCollection: "orders", sessionsCollection: "customers/{customerId}/payment-sessions", timeoutInMilliseconds: 60000 // 60 seconds timeout } }); // Access the payments API const paymentsAPI = client.payments; ``` -------------------------------- ### Firebase Extension Installation and Configuration Source: https://context7.com/summerhammer/firestore-liqpay-payments/llms.txt This section outlines the necessary steps and parameters for installing the Firestore LiqPay Payments extension via the Firebase CLI. It includes required configurations such as Cloud Functions region, Firestore collection names, LiqPay API keys, and optional JSONata expressions for mapping invoice data to LiqPay requests. ```yaml firebase ext:install summerhammer/firestore-liqpay-payments@0.2.1 # Required Configuration Parameters: LOCATION: us-central1 # Cloud Functions deployment region INVOICES_COLLECTION: invoices # Firestore collection for invoices SESSIONS_COLLECTION: checkout-sessions # Firestore collection for payment sessions LIQPAY_PUBLIC_KEY: your_public_key # From LiqPay account settings LIQPAY_PRIVATE_KEY: your_private_key # From LiqPay account settings LIQPAY_BASE_URL: https://www.liqpay.ua/api # LiqPay API endpoint WEBHOOK_URL: https://{LOCATION}-{PROJECT_ID}.cloudfunctions.net/ext-{EXT_INSTANCE_ID}-handlePaymentStatus HANDLE_INVOICE_PLACED_MIN_INSTANCES: 0 # Min function instances (0 or 1 recommended) # Optional JSONata Expression for Invoice Mapping: INVOICE_TO_CHECKOUT_REQUEST_JSONATA: | { "version": 3, "action": subscription.periodicity ? "subscribe" : "pay", "amount": amount, "currency": currency, "description": description, "order_id": invoiceId, "subscribe": $boolean(subscription.periodicity), "subscribe_date_start": subscription.start, "subscribe_periodicity": $lookup({"annually": "year", "monthly": "month", "weekly": "week", "daily": "day"}, subscription.periodicity) } ``` -------------------------------- ### Example LiqPay One-Time Checkout Request in TypeScript Source: https://context7.com/summerhammer/firestore-liqpay-payments/llms.txt Demonstrates how to construct a complete checkout request object for a one-time payment using the `EphemeralCheckoutRequest` interface. This example includes all necessary fields for a successful transaction, such as amount, currency, description, and callback URLs. ```typescript // Example: Complete checkout request for one-time payment const checkoutRequest: EphemeralCheckoutRequest = { version: 3, action: "pay", amount: 299.50, currency: "UAH", description: "Premium Membership - 1 Month", order_id: "order-20251114-001", server_url: "https://us-central1-myapp.cloudfunctions.net/ext-liqpay-handlePaymentStatus", result_url: "https://myapp.com/payment/success", expired_date: "2025-12-31 23:59:59", language: "en", paytypes: "card,liqpay", sender_first_name: "John", sender_last_name: "Doe", sender_city: "Kyiv", sender_country_code: "UA", product_name: "Premium Membership", product_category: "subscription", product_url: "https://myapp.com/premium" }; ``` -------------------------------- ### Example LiqPay Subscription Checkout Request in TypeScript Source: https://context7.com/summerhammer/firestore-liqpay-payments/llms.txt Provides an example of creating a checkout request object for a recurring subscription payment. This code snippet highlights the specific fields required for subscriptions, such as `subscribe`, `subscribe_date_start`, and `subscribe_periodicity`, in addition to standard payment details. ```typescript // Example: Subscription checkout request const subscriptionRequest: EphemeralCheckoutRequest = { version: 3, action: "subscribe", amount: 99.00, currency: "UAH", description: "Monthly Cloud Storage - 100GB", order_id: "sub-monthly-20251114-001", server_url: "https://us-central1-myapp.cloudfunctions.net/ext-liqpay-handlePaymentStatus", result_url: "https://myapp.com/subscription/activated", subscribe: "1", subscribe_date_start: "2025-12-01", subscribe_periodicity: "month", language: "en", product_name: "Cloud Storage 100GB" }; ``` -------------------------------- ### Firestore Security Rules for Invoices and Sessions (JavaScript) Source: https://context7.com/summerhammer/firestore-liqpay-payments/llms.txt Sets up Firestore security rules to protect 'invoices' and 'checkout-sessions' collections. It ensures users can only read or write their own data, and includes an example for multi-tenant setups using customer IDs. ```javascript rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { // Invoices collection - users can only read their own invoices match /invoices/{invoiceId} { allow read: if request.auth != null && request.auth.uid == resource.data.author_uid; allow create: if request.auth != null && request.auth.uid == request.resource.data.author_uid; } // Checkout sessions - users can read and write their own sessions match /checkout-sessions/{sessionId} { allow read, write: if request.auth != null && request.auth.uid == request.resource.data.author_uid; } // Multi-tenant with token substitution match /customers/{customerId}/sessions/{sessionId} { allow read, write: if request.auth != null && request.auth.uid == customerId; } } } ``` -------------------------------- ### Configure Subscription Payments with LiqPay Client (TypeScript) Source: https://context7.com/summerhammer/firestore-liqpay-payments/llms.txt Demonstrates how to configure and place recurring subscription invoices using the FirestoreLiqPayClient. It covers daily, weekly, monthly, and annual subscription models with specified amounts, currencies, and start dates. The code also shows how to wait for the checkout session. ```typescript import { FirestoreLiqPayClient } from "firestore-liqpay-node-client"; const client = FirestoreLiqPayClient.createDefault(); // Daily subscription const dailySubscription = { invoiceId: "daily-sub-001", amount: 10, currency: "UAH", description: "Daily News Digest", subscription: { periodicity: "daily", start: "2025-12-01" // Format: YYYY-MM-DD } }; // Weekly subscription const weeklySubscription = { invoiceId: "weekly-sub-002", amount: 50, currency: "UAH", description: "Weekly Premium Content", subscription: { periodicity: "weekly", start: "2025-12-01" } }; // Monthly subscription (most common) const monthlySubscription = { invoiceId: "monthly-sub-003", amount: 199, currency: "UAH", description: "Monthly Pro Membership", subscription: { periodicity: "monthly", start: "2025-12-01" } }; // Annual subscription const annualSubscription = { invoiceId: "annual-sub-004", amount: 1999, currency: "UAH", description: "Annual Enterprise Plan", subscription: { periodicity: "annually", start: "2025-12-01" } }; // Place subscription invoice const subId = await client.payments.placeInvoice(monthlySubscription); const session = await client.payments.waitForCheckoutSession(subId); console.log("Subscription payment URL:", session.paymentPageURL); // User completes payment on LiqPay, subscription is activated // LiqPay will automatically charge on the specified periodicity ``` -------------------------------- ### Cloud Firestore Security Rules Source: https://github.com/summerhammer/firestore-liqpay-payments/blob/main/POSTINSTALL.md Configures security rules for Cloud Firestore to restrict data access. It defines read access for invoices based on the author's UID and read/write access for sessions. Dependencies include Firebase project setup and parameter definitions for collection names. ```firestore rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /${param:INVOICES_COLLECTION}/{id} { allow read: if request.auth.uid == resource.data.author_uid; } match /${param:SESSIONS_COLLECTION}/{id} { allow read, write: if request.auth.uid == request.resource.data.author_uid; } } } ``` -------------------------------- ### Token Substitution for Multi-Tenant Applications Source: https://context7.com/summerhammer/firestore-liqpay-payments/llms.txt Demonstrates how to use token substitution in Firestore collection paths for organizing payment sessions in multi-tenant applications. This allows dynamic path resolution based on tenant identifiers. Dependencies include the 'firestore-liqpay-node-client'. ```typescript import { FirestoreLiqPayClient } from "firestore-liqpay-node-client"; // Configure client with token-based collection path const client = new FirestoreLiqPayClient({ payments: { invoicesCollection: "invoices", sessionsCollection: "customers/{customerId}/sessions" } }); // Invoice with customerId for token replacement const invoice = { customerId: "cust_abc123", // Token for path substitution amount: 500, currency: "UAH", description: "Enterprise Plan Upgrade" }; // Place invoice const invoiceId = await client.payments.placeInvoice(invoice); // Wait for session - provide tokens to resolve collection path const session = await client.payments.waitForCheckoutSession( invoiceId, { customerId: "cust_abc123" } // Resolves to: customers/cust_abc123/sessions/{invoiceId} ); console.log("Payment URL:", session.paymentPageURL); // Session stored at: customers/cust_abc123/sessions/{invoiceId} // Fetch existing session later const existingSession = await client.payments.fetchCheckoutSession( invoiceId, { customerId: "cust_abc123" } ); console.log("Current status:", existingSession.status); // Output: Current status: success ``` -------------------------------- ### Initiate Payment and Wait for Checkout Session URL Source: https://context7.com/summerhammer/firestore-liqpay-payments/llms.txt Initiates a payment by placing an invoice and then waits for the checkout session to be created, retrieving the payment page URL. It handles potential timeouts and internal errors during the payment initiation process. Dependencies include the 'firestore-liqpay-node-client'. ```typescript import { FirestoreLiqPayClient, CheckoutSession } from "firestore-liqpay-node-client"; const client = FirestoreLiqPayClient.createDefault(); async function initiatePayment(invoiceData: any) { try { // Step 1: Place the invoice const invoiceId = await client.payments.placeInvoice(invoiceData); // Step 2: Wait for checkout session with payment URL (default 30s timeout) const session: CheckoutSession = await client.payments.waitForCheckoutSession( invoiceId, {}, // No tokens needed for default collection path { timeoutInMilliseconds: 45000 } // Optional: 45s timeout ); if (session.paymentPageURL) { console.log("Redirect user to:", session.paymentPageURL); console.log("Session status:", session.status); // "pending" console.log("Created at:", session.createdAt); // Redirect user to session.paymentPageURL for payment return session.paymentPageURL; } } catch (error) { if (error.code === "timeout") { console.error("Payment session creation timed out"); } else if (error.code === "internal") { console.error("Payment initiation failed:", error.message); } throw error; } } // Example usage const paymentURL = await initiatePayment({ invoiceId: "inv-999", amount: 150, currency: "UAH", description: "Product Purchase" }); // Output: Redirect user to: https://www.liqpay.ua/checkout/abc123xyz... ``` -------------------------------- ### Initiate One-Time and Subscription Payments with Node.js Client Source: https://context7.com/summerhammer/firestore-liqpay-payments/llms.txt This code snippet illustrates how to use the Firestore LiqPay client to place invoices for both one-time and subscription payments. It covers creating invoice objects with necessary details like amount, currency, description, and subscription periodicity, then calling the `placeInvoice` method. ```typescript import { FirestoreLiqPayClient } from "firestore-liqpay-node-client"; const client = FirestoreLiqPayClient.createDefault(); // One-time payment invoice const oneTimeInvoice = { invoiceId: "order-12345", amount: 250.00, currency: "UAH", description: "Premium Subscription - 1 Month", customerEmail: "customer@example.com" }; try { // Place invoice - this creates document in Firestore and triggers handleInvoicePlaced const invoiceId = await client.payments.placeInvoice(oneTimeInvoice); console.log("Invoice placed with ID:", invoiceId); // Output: Invoice placed with ID: order-12345 } catch (error) { console.error("Failed to place invoice:", error.message); } // Subscription payment invoice const subscriptionInvoice = { invoiceId: "sub-67890", amount: 99.00, currency: "UAH", description: "Monthly Cloud Storage Subscription", subscription: { periodicity: "monthly", // "daily", "weekly", "monthly", "annually" start: "2025-12-01" } }; const subInvoiceId = await client.payments.placeInvoice(subscriptionInvoice); console.log("Subscription invoice ID:", subInvoiceId); // Output: Subscription invoice ID: sub-67890 ``` -------------------------------- ### Initialize FirestoreLiqpayClient in TypeScript Source: https://github.com/summerhammer/firestore-liqpay-payments/blob/main/clients/node/README.md Initializes the FirestoreLiqpayClient by providing the names of Firestore collections used for invoices and checkout sessions. Ensure the Firebase Admin SDK is initialized prior to this step. ```typescript import { FirestoreLiqpayClient } from "firestore-liqpay-node-client"; const client = new FirestoreLiqpayClient({ // The name of the Firestore collection where invoices are stored, it should // match the value of the `INVOICES_COLLECTION` parameter you set when // configuring the extension. invoicesCollection: "invoices", // The name of the Firestore collection where checkout sessions are stored, // it should match the value of the `SESSIONS_COLLECTION` parameter you set // when configuring the extension. sessionsCollection: "sessions", }); ``` -------------------------------- ### Place a new invoice for payment initiation in TypeScript Source: https://github.com/summerhammer/firestore-liqpay-payments/blob/main/clients/node/README.md Initiates a payment by placing a new invoice using the `placeInvoice` method. This method accepts a database object representation of the invoice and returns an invoice ID. Error handling for the process is included. ```typescript const client = FirestoreLiqpayClient.createDefault(); // Invoice here is your custom object that you use to track the payment, // it could be an order object or any other object that you want to associate // with the payment. const invoice = createInvoice(); try { const invoiceId: string = await client.payments.placeInvoice(invoice.toDatabaseObject()); console.log("Invoice placed successfully", invoiceId); } catch (error) { console.error("Failed to place invoice", error); } ``` -------------------------------- ### LiqPay Checkout Request Schema Source: https://context7.com/summerhammer/firestore-liqpay-payments/llms.txt Defines the structure for LiqPay API checkout requests for both one-time payments and subscriptions. ```APIDOC ## LiqPay Checkout Request This endpoint allows initiating payments or subscriptions through the LiqPay gateway. It supports various parameters for configuring the transaction, including amount, currency, description, and customer details. ### Method POST ### Endpoint /liqpay/checkout ### Parameters #### Request Body - **version** (number) - Required - LiqPay API version (always 3). - **action** (string) - Required - Payment type: "pay" or "subscribe". - **amount** (number) - Required - Payment amount. - **currency** (string) - Required - Currency code (e.g., "UAH", "USD", "EUR"). - **description** (string) - Required - Payment description. - **order_id** (string) - Required - Unique order identifier. - **server_url** (string) - Required - Webhook URL for status updates. - **result_url** (string) - Optional - Redirect URL after payment. - **expired_date** (string) - Optional - Payment expiration date and time (YYYY-MM-DD HH:MM:SS). - **paytypes** (string) - Optional - Allowed payment methods (e.g., "card,liqpay"). - **verifycode** (string) - Optional - Require SMS verification ("Y"). - **language** (string) - Optional - Interface language (e.g., "uk", "en", "ru"). - **subscribe** (string) - Optional - Enable subscription ("1"). Used when action is "subscribe". - **subscribe_date_start** (string) - Optional - First payment date for subscription (YYYY-MM-DD). - **subscribe_periodicity** (string) - Optional - Subscription periodicity ("day", "week", "month", "year"). - **sender_address** (string) - Optional - Customer address. - **sender_city** (string) - Optional - Customer city. - **sender_country_code** (string) - Optional - Country code (ISO 3166-1). - **sender_first_name** (string) - Optional - Customer first name. - **sender_last_name** (string) - Optional - Customer last name. - **sender_postal_code** (string) - Optional - Customer postal code. - **dae** (string) - Optional - Additional parameters as a JSON string. - **info** (string) - Optional - Additional information. - **product_category** (string) - Optional - Product category. - **product_description** (string) - Optional - Product description. - **product_name** (string) - Optional - Product name. - **product_url** (string) - Optional - Product page URL. ### Request Example (One-time Payment) ```json { "version": 3, "action": "pay", "amount": 299.50, "currency": "UAH", "description": "Premium Membership - 1 Month", "order_id": "order-20251114-001", "server_url": "https://us-central1-myapp.cloudfunctions.net/ext-liqpay-handlePaymentStatus", "result_url": "https://myapp.com/payment/success", "expired_date": "2025-12-31 23:59:59", "language": "en", "paytypes": "card,liqpay", "sender_first_name": "John", "sender_last_name": "Doe", "sender_city": "Kyiv", "sender_country_code": "UA", "product_name": "Premium Membership", "product_category": "subscription", "product_url": "https://myapp.com/premium" } ``` ### Request Example (Subscription) ```json { "version": 3, "action": "subscribe", "amount": 99.00, "currency": "UAH", "description": "Monthly Cloud Storage - 100GB", "order_id": "sub-monthly-20251114-001", "server_url": "https://us-central1-myapp.cloudfunctions.net/ext-liqpay-handlePaymentStatus", "result_url": "https://myapp.com/subscription/activated", "subscribe": "1", "subscribe_date_start": "2025-12-01", "subscribe_periodicity": "month", "language": "en", "product_name": "Cloud Storage 100GB" } ``` ### Response #### Success Response (200) - **redirect_url** (string) - The URL to redirect the user to for completing the payment. - **payment_id** (string) - The unique identifier for the initiated payment. #### Response Example ```json { "redirect_url": "https://pay.liqpay.ua/checkout/... "payment_id": "some_payment_id" } ``` ``` -------------------------------- ### Query Firestore LiqPay Sessions by Status (TypeScript) Source: https://context7.com/summerhammer/firestore-liqpay-payments/llms.txt Demonstrates how to retrieve checkout sessions from Firestore based on their payment status (pending, success, failure). It shows filtering by specific statuses and optionally by customer ID. This function is useful for monitoring payment states and implementing retry logic for failed payments. ```typescript import { FirestoreLiqPayClient, CheckoutSession } from "firestore-liqpay-node-client"; const client = FirestoreLiqPayClient.createDefault(); // Find all pending payment sessions const pendingSessions: CheckoutSession[] = await client.payments.findPendingCheckoutSessions(); console.log(`Found ${pendingSessions.length} pending payments`); pendingSessions.forEach(session => { console.log(`- Invoice ${session.invoiceId}: ${session.paymentPageURL}`); }); // Output: // Found 3 pending payments // - Invoice order-123: https://www.liqpay.ua/checkout/abc... // - Invoice order-456: https://www.liqpay.ua/checkout/def... // - Invoice order-789: https://www.liqpay.ua/checkout/ghi... // Find all successful payments const successfulSessions = await client.payments.findCheckoutSessionsWithStatus("success"); console.log(`Completed ${successfulSessions.length} payments`); // Find failed payments for retry logic const failedSessions = await client.payments.findCheckoutSessionsWithStatus("failure"); failedSessions.forEach(session => { console.log(`Failed: ${session.invoiceId} - ${session.errorMessage}`); }); // With token substitution for specific customer const customerPending = await client.payments.findCheckoutSessionsWithStatus( "pending", { customerId: "cust_abc123" } ); console.log(`Customer has ${customerPending.length} pending payments`); ``` -------------------------------- ### Define LiqPay Checkout Request Schema in TypeScript Source: https://context7.com/summerhammer/firestore-liqpay-payments/llms.txt This TypeScript interface outlines the complete structure for LiqPay API checkout requests. It includes all supported fields for one-time payments and subscriptions, specifying data types and optionality. This schema helps ensure valid request payloads are sent to the LiqPay API. ```typescript interface EphemeralCheckoutRequest { // Required fields version: 3; // LiqPay API version (always 3) action: "pay" | "subscribe"; // Payment type amount: number; // Payment amount currency: string; // Currency code (UAH, USD, EUR, etc.) description: string; // Payment description order_id: string; // Unique order identifier server_url: string; // Webhook URL for status updates // Optional payment configuration result_url?: string; // Redirect URL after payment expired_date?: string; // Payment expiration (YYYY-MM-DD HH:MM:SS) paytypes?: string; // Allowed payment methods (card, liqpay, etc.) verifycode?: string; // Require SMS verification ("Y") language?: string; // Interface language (uk, en, ru) // Subscription fields (when action: "subscribe") subscribe?: "1"; // Enable subscription subscribe_date_start?: string; // First payment date (YYYY-MM-DD) subscribe_periodicity?: "day" | "week" | "month" | "year"; // Customer information sender_address?: string; // Customer address sender_city?: string; // Customer city sender_country_code?: string; // Country code (ISO 3166-1) sender_first_name?: string; // First name sender_last_name?: string; // Last name sender_postal_code?: string; // Postal code // Additional data dae?: string; // Additional parameters (JSON string) info?: string; // Additional information product_category?: string; // Product category product_description?: string; // Product description product_name?: string; // Product name product_url?: string; // Product page URL } ``` -------------------------------- ### Firestore LiqPay Error Handling Patterns (TypeScript) Source: https://context7.com/summerhammer/firestore-liqpay-payments/llms.txt Illustrates how to handle various errors that may occur during payment processing using the Firestore LiqPay client. It specifically catches `FirestoreLiqPayError` and uses a switch statement to differentiate between error codes like 'timeout', 'internal', 'invalid-argument', and 'not-found'. This pattern enables graceful failure and implementing retry mechanisms for specific error types. ```typescript import { FirestoreLiqPayClient, FirestoreLiqPayError } from "firestore-liqpay-node-client"; const client = FirestoreLiqPayClient.createDefault(); async function robustPaymentFlow(invoiceData: any) { try { // Place invoice const invoiceId = await client.payments.placeInvoice(invoiceData); // Wait for checkout session const session = await client.payments.waitForCheckoutSession( invoiceId, {}, { timeoutInMilliseconds: 30000 } ); return { success: true, paymentURL: session.paymentPageURL }; } catch (error) { if (error instanceof FirestoreLiqPayError) { switch (error.code) { case "timeout": console.error("Checkout session creation timed out"); console.error("This usually means LiqPay API is slow or unavailable"); return { success: false, error: "timeout", retry: true }; case "internal": console.error("Internal error occurred:", error.message); console.error("Cause:", error.cause); return { success: false, error: "internal", retry: false }; case "invalid-argument": console.error("Invalid argument provided:", error.message); return { success: false, error: "validation", retry: false }; case "not-found": console.error("Checkout session not found:", error.message); return { success: false, error: "not-found", retry: false }; default: console.error("Unknown error:", error); return { success: false, error: "unknown", retry: false }; } } else { // Handle non-FirestoreLiqPayError console.error("Unexpected error:", error); return { success: false, error: "unexpected", retry: false }; } } } // Usage with retry logic let result = await robustPaymentFlow(invoiceData); if (!result.success && result.retry) { console.log("Retrying payment initiation..."); result = await robustPaymentFlow(invoiceData); } ``` -------------------------------- ### Wait for Checkout Session after invoice placement in TypeScript Source: https://github.com/summerhammer/firestore-liqpay-payments/blob/main/clients/node/README.md Waits for a checkout session to be created after an invoice has been placed. This method should be called in a separate event loop iteration to allow the extension to process the invoice. It returns a CheckoutSession object containing the payment page URL. ```typescript const client = FirestoreLiqpayClient.createDefault(); try { const session: CheckoutSession = await client.payments.waitForCheckoutSession(invoiceId); // Redirect the user to the payment page URL to complete the Checkout console.log("Payment Page URL:", session.paymentPageURL); } catch (error) { console.error("Failed to find checkout session", error); } ``` -------------------------------- ### Custom Invoice Mapping to LiqPay with JSONata (TypeScript) Source: https://context7.com/summerhammer/firestore-liqpay-payments/llms.txt Defines a custom invoice structure and demonstrates how to map it to LiqPay checkout request parameters using a JSONata expression. This allows for flexible data transformation between your application's invoice format and LiqPay's required fields. ```typescript const customInvoice = { id: "shop-order-789", customer: { name: "John Doe", email: "john@example.com" }, cart: { items: [ { name: "Product A", quantity: 2, price: 100 }, { name: "Product B", quantity: 1, price: 200 } ], total: 400, currencyCode: "UAH" }, billing: { type: "one-time", // or "recurring" period: null } }; // The extension will automatically transform the custom invoice to LiqPay format: // { // "version": 3, // "action": "pay", // "amount": 400, // "currency": "UAH", // "description": "Product A, Product B", // "order_id": "shop-order-789", // "product_name": "Product A + Product B", // "language": "en" // } ``` -------------------------------- ### CheckoutSession Data Model in TypeScript Source: https://context7.com/summerhammer/firestore-liqpay-payments/llms.txt This TypeScript interface defines the structure for a CheckoutSession object, which is stored in Firestore. It includes fields for status, payment URLs, invoice and transaction IDs, error details, and timestamps. This model helps standardize how payment session data is managed. ```typescript // Checkout Session Interface interface CheckoutSession { status: "pending" | "cancelled" | "success" | "failure"; paymentPageURL: string | null; // LiqPay payment page URL invoiceId: string; // Reference to invoice document transactionId: string | null; // LiqPay transaction ID (set on success) errorCode: string | null; // Error code if payment fails errorMessage: string | null; // Human-readable error message errorDetails: string | null; // Detailed error information createdAt: Date; // Document creation timestamp updatedAt: Date; // Last update timestamp } // Example Firestore document structure: // Collection: checkout-sessions // Document ID: order-12345 // { // "status": "success", // "paymentPageURL": "https://www.liqpay.ua/checkout/abc123...", // "invoiceId": "order-12345", // "transactionId": "1234567890", // "errorCode": null, // "errorMessage": null, // "errorDetails": null, // "createdAt": Timestamp(2025-11-14 10:30:00), // "updatedAt": Timestamp(2025-11-14 10:35:12) // } // Failed payment example: // { // "status": "failure", // "paymentPageURL": "https://www.liqpay.ua/checkout/xyz789...", // "invoiceId": "order-67890", // "transactionId": null, // "errorCode": "9999", // "errorMessage": "Insufficient funds", // "errorDetails": "Card has insufficient balance for this transaction", // "createdAt": Timestamp(2025-11-14 11:00:00), // "updatedAt": Timestamp(2025-11-14 11:02:30) // } ``` -------------------------------- ### Fetch Checkout Session Status Source: https://context7.com/summerhammer/firestore-liqpay-payments/llms.txt Retrieves the current payment status of an existing checkout session using the invoice ID. It logs detailed session information including status, transaction details, and timestamps. Handles cases where the session might not be found. Dependencies include the 'firestore-liqpay-node-client'. ```typescript import { FirestoreLiqPayClient, CheckoutSession } from "firestore-liqpay-node-client"; const client = FirestoreLiqPayClient.createDefault(); async function checkPaymentStatus(invoiceId: string) { try { const session: CheckoutSession = await client.payments.fetchCheckoutSession(invoiceId); console.log("Session Status:", session.status); console.log("Invoice ID:", session.invoiceId); console.log("Transaction ID:", session.transactionId); console.log("Payment URL:", session.paymentPageURL); console.log("Created:", session.createdAt); console.log("Updated:", session.updatedAt); switch (session.status) { case "success": console.log("Payment completed successfully!"); console.log("Transaction:", session.transactionId); // Grant access to purchased content break; case "pending": console.log("Payment is still pending"); // Show waiting status to user break; case "failure": console.error("Payment failed:"); console.error("Error Code:", session.errorCode); console.error("Error Message:", session.errorMessage); console.error("Error Details:", session.errorDetails); // Show error to user, offer retry break; case "cancelled": console.log("Payment was cancelled"); // Handle cancellation break; } return session; } catch (error) { if (error.code === "not-found") { console.error("Checkout session not found for invoice:", invoiceId); } throw error; } } // Example usage await checkPaymentStatus("order-12345"); // Output: // Session Status: success // Invoice ID: order-12345 // Transaction ID: 1234567890 // Payment URL: https://www.liqpay.ua/checkout/... ``` -------------------------------- ### Listen to Eventarc Payment Events in TypeScript Source: https://context7.com/summerhammer/firestore-liqpay-payments/llms.txt This code listens for various payment lifecycle events emitted via Eventarc, such as checkout session creation and updates. It processes these events to trigger actions like sending emails, granting user access, and updating analytics. Dependencies include firebase-functions and firebase-admin. ```typescript import { onCustomEvent } from "firebase-functions/v2/eventarc"; import * as admin from "firebase-admin"; // Listen for checkout session creation export const onCheckoutCreated = onCustomEvent( { eventType: "dev.summerhammer.firestore-liqpay-payments.v1.checkout-session.created", region: "us-central1" }, async (event) => { const invoiceId = event.subject; // Invoice ID const { paymentPageURL } = event.data; console.log(`Checkout created for invoice ${invoiceId}`); console.log(`Payment URL: ${paymentPageURL}`); // Send email notification to customer await sendPaymentLinkEmail(invoiceId, paymentPageURL); } ); // Listen for checkout session updates (status changes) export const onCheckoutUpdated = onCustomEvent( { eventType: "dev.summerhammer.firestore-liqpay-payments.v1.checkout-session.updated", region: "us-central1" }, async (event) => { const invoiceId = event.subject; const { status, transactionId } = event.data; console.log(`Checkout ${invoiceId} status changed to: ${status}`); if (status === "success") { // Grant access to purchased content await grantUserAccess(invoiceId, transactionId); // Update analytics await trackSuccessfulPayment(invoiceId, transactionId); // Send confirmation email await sendPaymentConfirmation(invoiceId); } else if (status === "failure") { // Log failed payment for analysis await logFailedPayment(invoiceId); // Notify support team await notifySupport(invoiceId); } } ); // Listen for payment status webhook receipt export const onPaymentStatusReceived = onCustomEvent( { eventType: "dev.summerhammer.firestore-liqpay-payments.v1.payment-status.received", region: "us-central1" }, async (event) => { const invoiceId = event.subject; const { status, transactionId } = event.data; console.log(`Received payment status from LiqPay: ${status}`); // Update custom analytics dashboard await updatePaymentMetrics(status, transactionId); } ); // Helper functions async function sendPaymentLinkEmail(invoiceId: string, paymentURL: string) { const db = admin.firestore(); const invoice = await db.collection("invoices").doc(invoiceId).get(); const customerEmail = invoice.data()?.customerEmail; // Send email using your email service console.log(`Sending payment link to ${customerEmail}: ${paymentURL}`); } async function grantUserAccess(invoiceId: string, transactionId: string) { const db = admin.firestore(); const invoice = await db.collection("invoices").doc(invoiceId).get(); const userId = invoice.data()?.author_uid; // Grant premium access await db.collection("users").doc(userId).update({ subscription: "premium", subscriptionStartDate: admin.firestore.FieldValue.serverTimestamp(), transactionId: transactionId }); console.log(`Granted premium access to user ${userId}`); } ``` -------------------------------- ### Cancel Firestore LiqPay Checkout Session (TypeScript) Source: https://context7.com/summerhammer/firestore-liqpay-payments/llms.txt Provides a function to manually cancel a pending payment session using its invoice ID. It includes steps to cancel the session and then fetch it again to verify the cancellation status. Optional customer ID can be provided for scoped cancellation. This is useful for managing orders where a customer explicitly requests cancellation or for administrative overrides. ```typescript import { FirestoreLiqPayClient } from "firestore-liqpay-node-client"; const client = FirestoreLiqPayClient.createDefault(); async function cancelPayment(invoiceId: string) { try { // Cancel the checkout session await client.payments.cancelCheckoutSession(invoiceId); console.log(`Payment session ${invoiceId} has been cancelled`); // Verify cancellation const session = await client.payments.fetchCheckoutSession(invoiceId); console.log("Updated status:", session.status); // Output: Updated status: cancelled } catch (error) { console.error("Failed to cancel payment:", error.message); } } // Cancel with token substitution await client.payments.cancelCheckoutSession( "order-12345", { customerId: "cust_abc123" } ); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.