Implement Charges Endpoint in the Open Event Android App
In the Open Event Android App we first create an attendee and then the order when a user tries to buy a ticket but the end user will only know that the transaction is successful when money gets deducted from his account. This is where we use the charges endpoint of the Open Event Server to complete the payment. Let’s see how this is being done in the Open Event Android App.
We are sending a POST request from the app to the following endpoint. The order identifier is added in the url to uniquely identify the order for which we are charging the user. The body of the POST request contains the Charge object with the required information.
@POST("orders/{orderIdentifier}/charge") fun chargeOrder(@Path("orderIdentifier") orderIdentifier: String, @Body charge: Charge): Single<Charge>
This is how the model class Charge looks like. We specify the type at the top. Then we can either send a stripe or paypal token to the server which contains all the details of the payment. Message and status fields are returned from the server after the getting a success response. The status is true if the payment has been successfully made otherwise it is false. The message field gives us the feedback about what kind of error we got if the payment was not successful otherwise we get a success response.
@Type("charge") data class Charge( @Id(IntegerIdHandler::class) val id: Int, val stripe: String? = null, val paypal: String? = null, val message: String? = null, val status: Boolean? = null )
This is how we send the stripe token to the server. If the card details are correct then we receive the stripe token in the onSuccess method and send it to the server using the Charges endpoint.
override fun onSuccess(token: Token) { //Send this token to server val charge = Charge(attendeeFragmentViewModel.getId().toInt(), token.id, null) attendeeFragmentViewModel.completeOrder(charge) }
This is the function that is being used to send the POST request. It takes a charge object as an argument and then we use that in the chargeOrder method. The orderIdentifier variable that we see in the chargeOrder function is a lateinit variable that gets initialized when an order has been returned from the server. When this request is being made in the background thread we show user the progress bar. When we receive a success response from the server, we update the value of the message variable with the value returned from the server and show it to the user. If the value of the status is true that means that the payment has been successfully completed.
fun completeOrder(charge: Charge) { compositeDisposable.add(orderService.chargeOrder(orderIdentifier.toString(), charge) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .doOnSubscribe { progress.value = true }.doFinally { progress.value = false }.subscribe({ message.value = it.message paymentCompleted.value = it.status if (it.status != null && it.status) { Timber.d("Successfully charged for the order!") } else { Timber.d("Failed charging the user") } }, { message.value = "Payment not completed!" Timber.d(it, "Failed charging the user") })) }
Resources
- ReactiveX official documentation: http://reactivex.io/
- Vogella RxJava 2 – Tutorial: http://www.vogella.com/tutorials/RxJava/article.html
- Androidhive RxJava Tutorial: https://www.androidhive.info/RxJava/