namespace GoodBooks.PAY.PAYDAL.Query.Order
{
///
/// SQL constants for TPAYORDER.
/// All queries MUST filter by TENANTID.
/// NOTE: TPAYORDER does NOT have a DATABASENAME column — filter by TENANTID only.
///
public static class PayOrderQB
{
// INDEX NOTES:
// TPAYORDER: PK_TPAYORDER — clustered on PAYORDERID
// → Used by GET_PAY_ORDER, UPDATE_PAY_ORDER_STATUS, UPDATE_PAY_ORDER_VOUCHERID
// TPAYORDER: IX_TPAYORDER_TENANTID_ORDERSTATUS
// — (TENANTID, ORDERSTATUS) INCLUDE (PAYORDERNO, CUSTOMERNAME, NETPAYABLEAMT, CREATEDON)
// → Used by GET_PAY_ORDER_LIST paged query
// TPAYORDER: IX_TPAYORDER_GATEWAYPAYORDERID_TENANTID
// — (GATEWAYPAYORDERID, TENANTID)
// → Used by GET_PAY_ORDER_BY_GATEWAY_ORDER_ID (webhook callback lookup)
// TPAYORDER: IX_TPAYORDER_TENANTID_SOURCEDOCTYPE_SOURCEDOCID
// — (TENANTID, SOURCEDOCTYPE, SOURCEDOCID) INCLUDE (ORDERSTATUS)
// → Used by COUNT_ACTIVE_ORDERS_FOR_SOURCEDOC (duplicate order guard)
public const string GET_PAY_ORDER = @"
SELECT
O.PAYORDERID AS PayOrderId,
O.PAYORDERNO AS PayOrderNo,
O.SOURCEDOCTYPE AS SourceDocType,
O.SOURCEDOCID AS SourceDocId,
O.CUSTOMERID AS CustomerId,
O.CUSTOMERNAME AS CustomerName,
O.CUSTOMEREMAIL AS CustomerEmail,
O.CUSTOMERPHONE AS CustomerPhone,
O.ORDERCURRENCY AS OrderCurrency,
O.ORDERAMT AS OrderAmt,
O.BASECURRENCY AS BaseCurrency,
O.BASEAMT AS BaseAmt,
O.EXCHANGERATE AS ExchangeRate,
O.COUPONDISCAMT AS CouponDiscAmt,
O.LOYALTYDISCAMT AS LoyaltyDiscAmt,
O.NETPAYABLEAMT AS NetPayableAmt,
O.PAYGATEWAYCONFID AS PayGatewayConfId,
O.GATEWAYPAYORDERID AS GatewayPayOrderId,
O.ORDERSTATUS AS OrderStatus,
O.PAIDAMT AS PaidAmt,
O.EXPIRESON AS ExpiresOn,
O.VOUCHERID AS VoucherId,
O.REMARKS AS Remarks,
G.PAYGATEWAYCODE AS GatewayCode,
G.PAYGATEWAYNAME AS GatewayName,
O.VERSION AS Version,
O.STATUS AS Status,
O.SORTORDER AS SortOrder,
O.CREATEDBYID AS CreatedById,
O.CREATEDON AS CreatedOn,
O.MODIFIEDBYID AS ModifiedById,
O.MODIFIEDON AS ModifiedOn,
O.SOURCETYPE AS SourceType,
O.TENANTID AS TenantId
FROM TPAYORDER O
LEFT JOIN MPAYGATEWAYCONFIG C ON C.PAYGATEWAYCONFID = O.PAYGATEWAYCONFID
LEFT JOIN MPAYGATEWAY G ON G.PAYGATEWAYID = C.PAYGATEWAYID
WHERE O.PAYORDERID = @PayOrderId
AND O.TENANTID = @TenantId";
// Entitlement↔Payment loose coupling (Docs/Platform-Architecture-Integration-
// Reference.md §9.1) — every order ever created for one SourceDoc (e.g. one
// subscription's full payment history: initial purchase + every renewal), newest
// first. Reuses the same (TENANTID, SOURCEDOCTYPE, SOURCEDOCID) index the duplicate-
// order guard already relies on — no new index needed.
public const string GET_PAY_ORDERS_BY_SOURCEDOC = @"
SELECT
O.PAYORDERID AS PayOrderId,
O.PAYORDERNO AS PayOrderNo,
O.SOURCEDOCTYPE AS SourceDocType,
O.SOURCEDOCID AS SourceDocId,
O.ORDERCURRENCY AS OrderCurrency,
O.ORDERAMT AS OrderAmt,
O.NETPAYABLEAMT AS NetPayableAmt,
O.ORDERSTATUS AS OrderStatus,
O.PAIDAMT AS PaidAmt,
G.PAYGATEWAYCODE AS GatewayCode,
G.PAYGATEWAYNAME AS GatewayName,
O.CREATEDON AS CreatedOn,
O.TENANTID AS TenantId
FROM TPAYORDER O
LEFT JOIN MPAYGATEWAYCONFIG C ON C.PAYGATEWAYCONFID = O.PAYGATEWAYCONFID
LEFT JOIN MPAYGATEWAY G ON G.PAYGATEWAYID = C.PAYGATEWAYID
WHERE O.SOURCEDOCTYPE = @SourceDocType
AND O.SOURCEDOCID = @SourceDocId
AND O.TENANTID = @TenantId
ORDER BY O.CREATEDON DESC";
public const string GET_PAY_ORDER_BY_GATEWAY_ORDER_ID = @"
SELECT
O.PAYORDERID AS PayOrderId,
O.PAYORDERNO AS PayOrderNo,
O.SOURCEDOCTYPE AS SourceDocType,
O.SOURCEDOCID AS SourceDocId,
O.CUSTOMERID AS CustomerId,
O.CUSTOMERNAME AS CustomerName,
O.CUSTOMEREMAIL AS CustomerEmail,
O.CUSTOMERPHONE AS CustomerPhone,
O.ORDERCURRENCY AS OrderCurrency,
O.ORDERAMT AS OrderAmt,
O.BASECURRENCY AS BaseCurrency,
O.BASEAMT AS BaseAmt,
O.EXCHANGERATE AS ExchangeRate,
O.COUPONDISCAMT AS CouponDiscAmt,
O.LOYALTYDISCAMT AS LoyaltyDiscAmt,
O.NETPAYABLEAMT AS NetPayableAmt,
O.PAYGATEWAYCONFID AS PayGatewayConfId,
O.GATEWAYPAYORDERID AS GatewayPayOrderId,
O.ORDERSTATUS AS OrderStatus,
O.PAIDAMT AS PaidAmt,
O.EXPIRESON AS ExpiresOn,
O.VOUCHERID AS VoucherId,
O.REMARKS AS Remarks,
G.PAYGATEWAYCODE AS GatewayCode,
G.PAYGATEWAYNAME AS GatewayName,
O.VERSION AS Version,
O.STATUS AS Status,
O.SORTORDER AS SortOrder,
O.CREATEDBYID AS CreatedById,
O.CREATEDON AS CreatedOn,
O.MODIFIEDBYID AS ModifiedById,
O.MODIFIEDON AS ModifiedOn,
O.SOURCETYPE AS SourceType,
O.TENANTID AS TenantId
FROM TPAYORDER O
LEFT JOIN MPAYGATEWAYCONFIG C ON C.PAYGATEWAYCONFID = O.PAYGATEWAYCONFID
LEFT JOIN MPAYGATEWAY G ON G.PAYGATEWAYID = C.PAYGATEWAYID
WHERE O.GATEWAYPAYORDERID = @GatewayPayOrderId
AND O.TENANTID = @TenantId";
public const string GET_PAY_ORDER_LIST = @"
SELECT
O.PAYORDERID AS PayOrderId,
O.PAYORDERNO AS PayOrderNo,
O.SOURCEDOCTYPE AS SourceDocType,
O.SOURCEDOCID AS SourceDocId,
O.CUSTOMERNAME AS CustomerName,
O.NETPAYABLEAMT AS NetPayableAmt,
O.ORDERSTATUS AS OrderStatus,
O.PAIDAMT AS PaidAmt,
G.PAYGATEWAYCODE AS GatewayCode,
O.CREATEDON AS CreatedOn,
O.TENANTID AS TenantId
FROM TPAYORDER O
LEFT JOIN MPAYGATEWAYCONFIG C ON C.PAYGATEWAYCONFID = O.PAYGATEWAYCONFID
LEFT JOIN MPAYGATEWAY G ON G.PAYGATEWAYID = C.PAYGATEWAYID
WHERE O.TENANTID = @TenantId
ORDER BY O.CREATEDON DESC
OFFSET @PageOffset ROWS FETCH NEXT @PageSize ROWS ONLY";
public const string COUNT_PAY_ORDER_LIST = @"
SELECT COUNT(1)
FROM TPAYORDER O
WHERE O.TENANTID = @TenantId";
///
/// Returns count of orders for a given source document that are not expired or cancelled.
/// OrderStatus: 1=Pending, 2=Processing, 3=Paid — excludes 4=Expired, 5=Cancelled, 6=Failed.
/// Used as a duplicate-order guard before InitiatePayOrder.
///
public const string COUNT_ACTIVE_ORDERS_FOR_SOURCEDOC = @"
SELECT COUNT(1)
FROM TPAYORDER O
WHERE O.TENANTID = @TenantId
AND O.SOURCEDOCTYPE = @SourceDocType
AND O.SOURCEDOCID = @SourceDocId
AND O.ORDERSTATUS IN (1, 2, 3)";
public const string INSERT_PAY_ORDER = @"
INSERT INTO TPAYORDER (
PAYORDERNO,
SOURCEDOCTYPE,
SOURCEDOCID,
CUSTOMERID,
CUSTOMERNAME,
CUSTOMEREMAIL,
CUSTOMERPHONE,
ORDERCURRENCY,
ORDERAMT,
BASECURRENCY,
BASEAMT,
EXCHANGERATE,
COUPONDISCAMT,
LOYALTYDISCAMT,
NETPAYABLEAMT,
PAYGATEWAYCONFID,
GATEWAYPAYORDERID,
ORDERSTATUS,
PAIDAMT,
EXPIRESON,
VOUCHERID,
REMARKS,
VERSION,
STATUS,
SORTORDER,
CREATEDBYID,
CREATEDON,
MODIFIEDBYID,
MODIFIEDON,
SOURCETYPE,
TENANTID
) VALUES (
@PayOrderNo,
@SourceDocType,
@SourceDocId,
@CustomerId,
@CustomerName,
@CustomerEmail,
@CustomerPhone,
@OrderCurrency,
@OrderAmt,
@BaseCurrency,
@BaseAmt,
@ExchangeRate,
@CouponDiscAmt,
@LoyaltyDiscAmt,
@NetPayableAmt,
@PayGatewayConfId,
@GatewayPayOrderId,
@OrderStatus,
@PaidAmt,
@ExpiresOn,
@VoucherId,
@Remarks,
@Version,
@Status,
@SortOrder,
@CreatedById,
@CreatedOn,
@ModifiedById,
@ModifiedOn,
@SourceType,
@TenantId
)";
///
/// Targeted status update — used by webhook callback and payment return handler.
/// Only updates ORDERSTATUS, GATEWAYPAYORDERID, PAIDAMT, and audit fields.
/// Does NOT update financial amounts to prevent accidental overwrites.
///
public const string UPDATE_PAY_ORDER_STATUS = @"
UPDATE TPAYORDER SET
ORDERSTATUS = @OrderStatus,
GATEWAYPAYORDERID = @GatewayPayOrderId,
PAIDAMT = @PaidAmt,
MODIFIEDBYID = @ModifiedById,
MODIFIEDON = @ModifiedOn
WHERE PAYORDERID = @PayOrderId
AND TENANTID = @TenantId";
///
/// Updates the VoucherId after the Finance module posts the receipt voucher.
/// Called from Finance receipt-posting flow after successful payment confirmation.
///
public const string UPDATE_PAY_ORDER_VOUCHERID = @"
UPDATE TPAYORDER SET
VOUCHERID = @VoucherId,
MODIFIEDBYID = @ModifiedById,
MODIFIEDON = @ModifiedOn
WHERE PAYORDERID = @PayOrderId
AND TENANTID = @TenantId";
}
}