Newer
Older
import androidx.lifecycle.lifecycleScope
import com.stripe.android.PaymentConfiguration
import com.stripe.android.paymentsheet.PaymentSheet
import com.stripe.android.paymentsheet.PaymentSheetResult
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.net.URL
class PaymentManager {
private val _fragment: Fragment;
private val _overlayContainer: ViewGroup;
private val _sheet: PaymentSheet;
private val _paymentState: PaymentState;
constructor(paymentState: PaymentState, fragment: Fragment, overlayContainer: ViewGroup, listener: PaymentStatusListener) {
_fragment = fragment;
_paymentState = paymentState;
_overlayContainer = overlayContainer;
_sheet = PaymentSheet(_fragment) { paymentSheetResult ->
when(paymentSheetResult) {
is PaymentSheetResult.Canceled -> {
}
}
};
}
fun startPayment(paymentState: PaymentState, scope: CoroutineScope, productId: String) {
scope.launch(Dispatchers.IO){
try{
val availableCurrencies = _paymentState.getAvailableCurrencies(productId);
val country = paymentState.getPaymentCountryFromIP()?.let { c -> PaymentConfigurations.COUNTRIES.find { it.id.equals(c, ignoreCase = true) } };
SlideUpPayment.startPayment(paymentState, _overlayContainer, productId, country, availableCurrencies, { method, request ->
when(method) {
"stripe" -> startPaymentStripe(productId, request.currency, request.mail, request.country, request.zipcode);
}
}
}
catch(ex: Throwable) {
Log.e(TAG, "startPayment failed", ex);
scope.launch(Dispatchers.Main){
UIDialogs.showGeneralErrorDialog(_fragment.requireContext(), "Failed to get required payment data (did you grant the app network permission?)", ex, onOk = { _listener.onCancel() });
}
}
}
}
private fun startPaymentStripe(productId: String, currency: String, email: String, country: String? = null, zipcode: String? = null) {
_fragment.lifecycleScope.launch(Dispatchers.IO) {
try {
Log.i("BuyFragment", "Starting payment");
val paymentIntentResult = _paymentState.getPaymentIntent(productId, currency, email, country, zipcode);
val customerConfig = if(paymentIntentResult.customer != null && paymentIntentResult.ephemeralKey != null)
PaymentSheet.CustomerConfiguration(paymentIntentResult.customer, paymentIntentResult.ephemeralKey);
else null;
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
PaymentConfiguration.init(_fragment.requireContext(), paymentIntentResult.publishableKey);
withContext(Dispatchers.Main) {
_sheet.presentWithPaymentIntent(
paymentIntentResult.paymentIntent, PaymentSheet.Configuration(
merchantDisplayName = "FUTO",
customer = customerConfig,
allowsDelayedPaymentMethods = true,
defaultBillingDetails = PaymentSheet.BillingDetails(PaymentSheet.Address(country = country, postalCode = zipcode), email),
billingDetailsCollectionConfiguration = PaymentSheet.BillingDetailsCollectionConfiguration(
email = PaymentSheet.BillingDetailsCollectionConfiguration.CollectionMode.Always
)
)
);
}
}
catch(ex: Throwable) {
Log.e(TAG, "Payment failed: ${ex.message}", ex);
withContext(Dispatchers.Main) {
UIDialogs.showGeneralErrorDialog(_fragment.requireContext(), "Payment failed\nIf you are charged you should always receive the key in your mail.", ex);
}
}
}
}
//TODO: Determine a good provider
data class PaymentRequest(
val productId: String,
val currency: String,
val mail: String,
val country: String? = null,
val zipcode: String? = null
);
companion object {
private const val TAG = "PaymentManager"
}
}