forked from thijooree/android
ooredoo billpay via bml card
This commit is contained in:
@@ -12,10 +12,10 @@ import java.util.Locale
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
/**
|
||||
* Ooredoo prepaid recharge (Raastas) through the ooredoo.mv Quick Pay page, paid by card on
|
||||
* BML's merchant gateway. Ooredoo only creates the order; the money moves on the BML Merchant
|
||||
* Services transaction it hands back, which is paid like any card-only BML merchant link. See
|
||||
* `docs/ooredooapi/02-raastas.md`.
|
||||
* Ooredoo prepaid recharge (Raastas) and bill payment through the ooredoo.mv Quick Pay pages,
|
||||
* paid by card on BML's merchant gateway. Ooredoo only creates the order; the money moves on the
|
||||
* BML Merchant Services transaction it hands back, which is paid like any card-only BML merchant
|
||||
* link. See `docs/ooredooapi/02-raastas.md` and `docs/ooredooapi/03-bill-pay.md`.
|
||||
*
|
||||
* Every call blocks, so run it on an IO thread.
|
||||
*/
|
||||
@@ -32,15 +32,29 @@ class OoredooPaymentClient {
|
||||
* that plus GST. Returns the 24-hex BML transaction id. Throws with Ooredoo's wording when
|
||||
* the order is refused.
|
||||
*/
|
||||
fun createRaastasTransaction(number: String, amount: Int, charged: BigDecimal): String {
|
||||
fun createRaastasTransaction(number: String, amount: Int, charged: BigDecimal): String =
|
||||
createOrder(number, charged, amount.toString(), transType = "recharge", serviceType = "prepaid")
|
||||
|
||||
/**
|
||||
* Creates the bill payment order for postpaid [number] (7 digits) and the BML transaction
|
||||
* paying for it. [amount] is MVR, up to 2 decimal places; no GST. Returns the 24-hex BML
|
||||
* transaction id. Throws with Ooredoo's wording when the order is refused.
|
||||
*/
|
||||
fun createBillPayTransaction(number: String, amount: BigDecimal): String =
|
||||
createOrder(number, amount, money(amount), transType = "billpay", serviceType = "Mobile")
|
||||
|
||||
/** `POST PaymentGateway/bml` — one call makes the order and its BML transaction. */
|
||||
private fun createOrder(
|
||||
number: String, charged: BigDecimal, amountWithoutGst: String, transType: String, serviceType: String,
|
||||
): String {
|
||||
val msisdn = "960$number"
|
||||
val body = JSONObject()
|
||||
.put("msisdn", msisdn)
|
||||
.put("purchaseAmount", String.format(Locale.US, "%.2f", charged.setScale(2, RoundingMode.HALF_UP)))
|
||||
.put("amountWithoutGst", amount.toString())
|
||||
.put("purchaseAmount", money(charged))
|
||||
.put("amountWithoutGst", amountWithoutGst)
|
||||
.put("receiverMsisdn", msisdn)
|
||||
.put("transType", "recharge")
|
||||
.put("serviceType", "prepaid")
|
||||
.put("transType", transType)
|
||||
.put("serviceType", serviceType)
|
||||
.put("serviceTypeDisplayName", "Mobile")
|
||||
val text = client.newCall(
|
||||
Request.Builder().url("$BASE/ooredoo-prod/PaymentGateway/bml")
|
||||
@@ -48,7 +62,6 @@ class OoredooPaymentClient {
|
||||
.header("User-Agent", UA)
|
||||
.header("Accept", "application/json")
|
||||
.header("Origin", BASE)
|
||||
.header("Referer", "$BASE/payment?source=Recharge&transType=2")
|
||||
.build()
|
||||
).execute().use { r ->
|
||||
if (r.code in 500..599) throw BankServerException("Ooredoo")
|
||||
@@ -58,13 +71,16 @@ class OoredooPaymentClient {
|
||||
throw Exception("Unexpected response from Ooredoo")
|
||||
}
|
||||
if (obj.optString("status") != "OK" || obj.optString("code") != "2000") {
|
||||
throw Exception(obj.optString("msg").ifBlank { "Ooredoo refused the recharge" })
|
||||
throw Exception(obj.optString("msg").ifBlank { "Ooredoo refused the payment" })
|
||||
}
|
||||
val data = obj.optJSONObject("data") ?: throw Exception("Ooredoo didn't create the order")
|
||||
return TXN_URL.find(data.optString("bmlUrl"))?.groupValues?.get(1)
|
||||
?: throw Exception("BML didn't create the transaction")
|
||||
}
|
||||
|
||||
private fun money(amount: BigDecimal) =
|
||||
String.format(Locale.US, "%.2f", amount.setScale(2, RoundingMode.HALF_UP))
|
||||
|
||||
companion object {
|
||||
private const val BASE = "https://www.ooredoo.mv"
|
||||
private const val UA = "Mozilla/5.0 (X11; Linux x86_64; rv:150.0) Gecko/20100101 Firefox/150.0"
|
||||
|
||||
@@ -22,8 +22,8 @@ import java.math.RoundingMode
|
||||
* A carrier service a verified BML card can pay, through the carrier's own website and its BML
|
||||
* merchant gateway. The limits are the carrier website's, not Fahipay's.
|
||||
*
|
||||
* No Ooredoo bill pay yet. Add it as a constant once its send path lands; the exhaustive `when`s
|
||||
* over this enum point at every site that needs updating.
|
||||
* Add new services as constants; the exhaustive `when`s over this enum point at every site that
|
||||
* needs updating.
|
||||
*/
|
||||
enum class CardPayoutService(
|
||||
override val label: String,
|
||||
@@ -46,7 +46,9 @@ enum class CardPayoutService(
|
||||
minAmount = 1, maxAmount = null, decimalsAllowed = true, gstPercent = null),
|
||||
// Ooredoo credits the whole amount and charges the card 8% GST on top
|
||||
OOREDOO_RAASTAS("Raastas", "Ooredoo · Raastas", R.drawable.ooredoo_logo,
|
||||
minAmount = 20, maxAmount = null, decimalsAllowed = false, gstPercent = 8, gstAdded = true);
|
||||
minAmount = 20, maxAmount = null, decimalsAllowed = false, gstPercent = 8, gstAdded = true),
|
||||
OOREDOO_BILL("Ooredoo Bill Pay", "Ooredoo · Bill Pay", R.drawable.ooredoo_logo,
|
||||
minAmount = 10, maxAmount = null, decimalsAllowed = true, gstPercent = null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -95,6 +97,9 @@ class CardPayoutTransferHandler(
|
||||
if (result.ooredoo == OoredooClient.CustType.PRE || result.ooredoo == OoredooClient.CustType.HYBRID) {
|
||||
add(CardPayoutService.OOREDOO_RAASTAS)
|
||||
}
|
||||
if (result.ooredoo == OoredooClient.CustType.POST || result.ooredoo == OoredooClient.CustType.HYBRID) {
|
||||
add(CardPayoutService.OOREDOO_BILL)
|
||||
}
|
||||
}.map { TransferType.Card(it, result.ownerName, cards) }
|
||||
}
|
||||
|
||||
@@ -166,6 +171,8 @@ class CardPayoutTransferHandler(
|
||||
DhiraaguPaymentClient().createBillPayTransaction(number, amount)
|
||||
CardPayoutService.OOREDOO_RAASTAS ->
|
||||
OoredooPaymentClient().createRaastasTransaction(number, amount.intValueExact(), charged)
|
||||
CardPayoutService.OOREDOO_BILL ->
|
||||
OoredooPaymentClient().createBillPayTransaction(number, amount)
|
||||
}
|
||||
BmlMerchantTxnClient().fetchPayPage(txnId)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user