Addendum for payments

The page detailing the analysis of contributions and modules only detailed a part of the complete payment process, mostly managed from the C# REST API. After consulting with SwissTPH regarding test cases, it became apparent that the payment process was in fact more complex than what was described.

API versions

While the various payment APIs are based on the same REST interface, there are two versions in the main branch and SwissTPH added a separate branch with a lot of adaptations for the Gepg payment gateway. The test case being based on that branch, we will mainly focus on it for this document.

More details about the Tanzania Gepg adaptation are available here:

 

Payment status

The Control Number can be assigned externally or generated by OpenIMIS itself, this leads to a slightly different process.

General process

Taken from https://openimis.atlassian.net/wiki/spaces/OP/pages/963182778/Events+2019?preview=%2F963182778%2F907378784%2FTZ%20mobile%20phone%20integration.pdf

CHF-IMIS process (Tanzania)

The process in Tanzania is triggered by people calling the payment system.

Create a payment intent (+ control number)

API: POST /api/GetControlNumber

This step typically takes payment information like the mobile phone number and the list of policies to pay. This will create a single entry in the payment table and an entry in payment_details for each policy to pay (new or renew).

In the V1 API, this call only does basic processing while V2 and SwissTPH branch do a lot more at once.

Sample request:

{ "phone_number": "0681333045", "request_date": "2021-03-12", "enrolment_officer_code": "E00005", "policies": [ { "insurance_number": "070707070", "insurance_product_code": "FCUL0001", "renewal": 1 } ], "amount_to_be_paid": 21000, "language": "en", "type_of_payment": 1, "smsRequired": true }

Response:

{ "error_occured": false, "error_message": "Success", "internal_identifier": "24", "control_number": "805315" }

Note: the control_number might be present if the payment gateway implementation does provide it or provided in the request (to be verified).

=> Payment status: 1 not yet confirmed if CN generated or 3 assigned

See below for the details of this procedure

(generated) Get assigned control numbers

API: POST /api/GetAssignedControlNumbers

Request:

{ "requests": [ { "internal_identifier": "24" } ] }

Response:

(generated) Acknowledge control number

API: POST /api/PostReqControlNumberAck

=> Payment status: 2 posted

(external) Receive external control number

API: POST /api/GetReqControlNumber

 

=> Payment status: 3 assigned

Payment confirmation

API: POST /api/GetPaymentData

 

response:

 

=> Payment status: 4

Match Payment

API: POST /api/MatchPayment

 

Request:

Response:

=> Payment status: 5 matched

 

Create Payment Intent details

Proxy families

When enrolling families offline, it is possible to receive a payment for an unknown family. These are called “proxy family” and have a specific process given that their policies are unknown and cannot be valuated properly.

GetControlNumber / create payment intent

  • PaymentController.GetControlNumber

    • PaymentLogic.SaveIntent()

      • PaymentRepository.SaveIntent()

        • uspInsertPaymentIntent (see below)

        • Response from stored proc: payment_id => internal_identifier, control_number is always null

        • Determines whether the language in Primary or Alternate

        • SaveIntentResponse (list of error messages)

        • GetPaymentInfo (big query and converting for detailed payment response)

      • => List(AssignedControlNumber)

      • determineTransferFee (defaults to 0)

      • UpdatePaymentTransferFee

      • GetToBePaidAmount (expected_amount - transfer_fee, rounded 2 dec)

      • PostReqControlNumber

      • CheckControlNumber (if specified)

      • SaveControlNumber

      • ControlNumberAssignedSms or ControlNumberNotassignedSms

      • SaveControlNumberAkn (if error, adds ControlNumberNotassignedSms)

uspInsertPaymentIntent()

Parse XML

ProxySettings are parsed

Validations:

  • Insuree number not specified (proxy families have a number but not yet known)

  • EO code

  • Product code

  • EO + Product incompatible

  • Policy exists and ready to renew (no real renewal check)

  • Proxy family cannot renew 🤷🏻‍♂️

  • If prior enrolment specified (call parameters) and a valid policy exists, reject

 

For each policy:

If the insuree exists:

If amount is 0, compute it

    If renewal requested, policy stage = ‘R’ otherwise ‘N’

    Retrieve family, product and policy ids

    If EO

        If there are premiums already, collect the remaining value to pay (this stage will fail if there are several outstanding premiums for the target policy)

        Else compute the policy value

    Else

        If policy is new, compute its value

        Else take the latest policy

            If the policy status is idle, take the policy value

            Else compute the policy value

If the insuree doesn’t exist, call the uspPolicyValueProxyFamily

 

Output of last section: policy value and policy stage

 

Insert Payment with the total expected amount and the Payment Details with the specifics.

 

 

Did you encounter a problem or do you have a suggestion?

Please contact our Service Desk



This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License. https://creativecommons.org/licenses/by-sa/4.0/