HSRCPAY Documentation

Data Models - Payments & Charges

Public/conceptual fields of Payment and Charge objects, normalized model, and separation from provider raw data.

This page explains the public/conceptual model of Payment and Charge objects. The goal is not to expose the private database schema one-to-one, but to help merchants and developers understand which field carries which responsibility.

In HSRC Pay the public integration model should rely on normalized fields. Raw provider response may be stored for debug, trace, or internal ops; merchant applications should decide from normalized fields.

Model design principles

  • Payment is business-level payment intent.
  • Charge is provider-level attempt or financial transaction attempt.
  • Provider raw data does not replace the public model.
  • Metadata carries merchant context; do not use it for secrets, card data, or provider credentials.
  • Security/3DS fields are sensitive and should be masked.
  • Public fields should stay stable and explainable for backward compatibility.

Payment object

FieldTypeDescriptionWhen populatedImportance for merchant
idstringPayment identifierAt createOrder/payment matching
amountintegerAmount in minor unitAt createFinancial intent
currencystringCurrencyAt createProvider capability and settlement context
statusstringPayment lifecycle stateThroughout lifecycleMerchant order state
customer_idstring/nullCustomer relationshipAt create if presentCustomer tracking
checkout_session_idstring/nullHosted checkout relationshipIn checkout flowLinks session to payment
routing_originstring/nullLast confirm routing originAfter confirmmerchant_direct, autopilot, etc.
installmentsnumber/nullInstallment countAt createnull or 1 for single charge
metadataobjectMerchant-defined contextCreate/updateOrder, tenant, or internal reference
created_at / updated_attimestampTimestampsSystemAudit and operations

secure_mode, auto_capture, and next_action are used during create/confirm; confirm response carries platform redirect in confirmResult.paymentNextAction (redirect_user_to_url). List/detail DTO may not show all internal fields always; see include_* query flags for expansion.

Charge object

FieldTypeDescriptionProvider relationshipNotes
idstringCharge attempt identifierLinked to provider attemptMultiple per Payment possible
payment_idstringParent Payment relationshipGroups attempts under same PaymentCritical for reporting
attempt_nointeger/nullAttempt sequenceRouting plan indexUsed for trace
statusstringCharge lifecycle stateUpdated from provider resultAuthorized/captured/declined distinction
amountintegerAttempted amountProvider request amountShould align with payment amount
authorized_amountnumberAuthorized amountAfter authImportant before capture
captured_amountnumberCaptured amountAfter captureFinancial closure
refunded_amountnumberTotal refundedAfter refundRefund reporting
payment_provider_idstring/nullProvider identifierSelected providerOperational monitoring
routing_plan_idstring/nullRouting plan relationshipCandidate selectionFallback analysis
routing_originstring/nullRouting originRouting engineOperational visibility
securityobject/null3DS/security subsetOrchestrator/adapter mergeSensitive fields should be masked
transactionobject/nullNormalized transaction subsetOrchestrator/adapter mergeNot raw provider response

Payment vs Charge comparison

TopicPaymentCharge
LevelMerchant/businessProvider/rail
CountUsually one per orderMultiple possible per Payment
PurposeHolds payment intent and final stateHolds attempt, authorization, capture, and provider trace
Webhook effectMain source for merchant order stateOperational detail and reconciliation
Routing effectPayment stays the sameFallback may create new charge attempt

State fields

Payment state affects merchant order lifecycle. Charge state describes provider attempt status.

Example conceptual state families:

  • Payment: CREATED, REQUIRES_PAYMENT_METHOD, REQUIRES_ACTION, PROCESSING, AUTHORIZED, SUCCEEDED, CANCELED, REFUNDED, EXPIRED
  • Charge: CREATED, REQUIRES_ACTION, AUTHORIZED, REQUIRES_CAPTURE, PARTIALLY_CAPTURED, CAPTURED, CANCELED, FAILED, REFUNDED, EXPIRED, DECLINED

Payment has no DECLINED; read decline as Charge DECLINED + Payment REQUIRES_PAYMENT_METHOD.

Use API Reference as source of truth for current enums and response contract.

Amount/currency fields

Amount fields should be designed in minor units. Payment amount is business target; Charge amount is provider attempt amount.

For partial capture or partial refund, interpret Charge capturedAmount and refundedAmount together with Payment top-level state.

Provider references

Provider reference fields are useful for reconciliation and support. However, the full provider raw response should not be treated as the merchant API contract.

Provider-specific fields may change; merchant applications should rely on normalized status, kind, errCode, providerRef, and traceId style public fields.

Metadata

Metadata carries merchant context:

  • Order ID
  • Tenant/workspace reference
  • Campaign or invoice reference
  • Internal reporting key

Do not put card data, CVV, provider credentials, secrets, signature material, or sensitive PII in metadata.

Security/3DS fields

3DS, secure mode, and security fields after challenge may vary by provider. In the public model these fields should be limited, masked, and normalized.

Example:

{
  "security": {
    "secureModeUsed": true,
    "threeDSResult": "authenticated",
    "liabilityShift": "unknown_or_provider_specific"
  }
}

This example is conceptual; do not expose real provider security payloads or sensitive fields in public docs.

Event payload relationship

Webhook/event payloads carry Payment state changes to merchant backend. Charge details may be summarized in events or queried via API.

Trust Payment events for merchant order state; use Charge and Routing trace fields for provider attempt analysis.

Example JSON

{
  "object": "payment",
  "id": "pay_123",
  "amount": 100000,
  "currency": "TRY",
  "status": "SUCCEEDED",
  "metadata": { "order_id": "ord_987" },
  "charges": [
    {
      "object": "charge",
      "id": "ch_1",
      "payment_id": "pay_123",
      "attempt_no": 1,
      "status": "DECLINED",
      "amount": 100000,
      "routing_origin": "merchant_direct"
    },
    {
      "object": "charge",
      "id": "ch_2",
      "payment_id": "pay_123",
      "attempt_no": 2,
      "status": "CAPTURED",
      "amount": 100000,
      "routing_origin": "fallback"
    }
  ]
}

Backward compatibility notes

  • Public response fields should evolve with backward compatibility during migration.
  • Private database column names are not the public API contract.
  • Merchant integration should be built on the normalized model, not raw provider response.
  • When new provider capability or result family is added, docs and SDK behavior should be updated together.

On this page