Mobile in-app purchases Integration Proposal

This document gives a tentative plan on how to integrate In-App purchases for course seats in the edX mobile apps.

Scope

This document’s scope covers the changes required in the OpenedX ecommerce backend to integrate in-app purchases in the mobile apps.

Proposal Flow:

Note: It is presumed that the user is already signed in and is present on the course detail page of the to-be-purchased course

  1. The learner clicks on the upgrade course button

  2. The learner is presented with the in-app purchase pop up

  3. The learner enters and submits the payment details

  4. The mobile payment system verifies the payment

  5. Upon successful payment, the in-app purchase fulfillment API on the ecommerce side is called with the transaction details (like the receipt number) and purchased course seat information (SKU).

  6. The transaction is verified by a third-party app (e.g. InAppPy)

  7. Once the transaction is confirmed, the following steps will be carried out on the ecommerce side:

    • The purchased course seat is added to the basket

    • An open order is created against the purchased seat

    • The order is fulfilled by the ecommerce worker

    • The order is marked completed

  8. After the fulfillment is completed, the mobile side is intimated which in turn refreshes the unlocked course content or displays the order receipt

 

API additions and changes:

Following API additions are expected:

  • In-App purchase fulfillment API

    • API that verifies the payment and unlocks gated content

    • Possible data required for this API:

      • Transactional details like receipt information or Transaction ID

      • Basket, which can be obtained for a user against a site

  • We would probably need to alter or create a similar API to the BasetAddItemsView API that returns a JSON response for product addition to the basket instead

    of a redirect that is happening right now.

  • In addition to this, we would need to be able to distinguish between in-app purchase orders and web orders. The most straightforward way of doing this is to add a boolean flag to the Order model. We could add a card_type choice to the already present Source model with the relevant information about android/iOS IAP for this purpose.

API Flow:

Following is the proposed API flow:

  1. BasketAddItemsView is called with the course seat SKU to get it added to the basket on the ecommerce side before showing the payment pop-up on the app screen
    Note: The embargo check would apply at this point and the API call would fail if a user is requesting from a country with the embargo in place.

  2. Payment is processed on the mobile side. Upon success, the newly introduced In-app purchase fulfillment API is called with the transaction ID or other transaction information

  3. A third party in-app purchase verifier verifies the successful purchase

  4. Upon successful verification, create_order from EdxOrderPlacementMixin is called to create and place an order against the purchased course seat.

  5. The create_order method creates the order, places it with the system, and triggers the course seat fulfillment.

  6. Once this is all complete, some post order operations like invoice creation are carried out by the handle_post_order method.

  7. Once these steps are complete, the user should have access to gated content as well as all the journalling be done on the ecommerce side.

  8. The in-app Purchase API then returns a success response to the mobile app and the flow is continued on the mobile side.

 

Procedure to offer a refund:

There are APIs already in place to create and track refunds which are as follows:

  • <http-scheme>://<domain>/refunds/

  • <http-scheme>://<domain>/refunds/<pk>/process/

The first API creates a refund and the second API can be used to approve or deny a refund.

These APIs can be used as is in the case of web orders but since the payment is being processed on the mobile end in the in-app purchases, further research would be needed to figure out exactly where these APIs would fit in.

Risks and Concerns:

Following are some of the visible potential concerns that are attached to the in-app purchases flow:

  • What if there is a network/connection problem to the server and the course seat purchase fulfillment call fails?

    • Possible routes:

      • Mobile side retries calling the API

      • Triggers the fallback if the issue persists

  • What would happen if the in-app purchase verification fails?

    • Possible routes:

      • Retry verification

      • Let the mobile side know that the verification failed to trigger the fallback

  • What would happen if the order fulfillment fails?

    • Possible routes:

      • Retry fulfillment?

      • Mobile side fallback

  • Apart from the above points of failure in the IAP fulfillment flow, a potential risk lies in the selection of the IAP verification library. Since IAP verification is a crucial step in fulfilling the purchase, this could be a potential blocker as well. Currently, the library under consideration is InAppPy. If for any reason, this library does not work out, we would be facing the following scenarios:

    • We might need to wait for a fix for the faced issue from the library developers

    • We could be on a look for a new IAP verification library

    • The worst-case scenario would be the selected library not working out and no other suitable library found as well

 

Project Estimates:

Project tasks:

  • In-App purchase verification and order fulfillment API for AppStore payments(~2 weeks)

  • In-App purchase verification and order fulfillment API for play store payments(~2 weeks)

  • Any modifications required in the current system like changes to the Order module to distinguish mobile In-app orders from other orders (~1 week)