Using No-Codes with custom purchases handling
By default, Qonversion No-Codes utilize the Qonversion SDK for managing purchases. This implies that you should operate Qonversion in subscription management mode. However, if you have your own purchasing infrastructure, you can manage purchases and restores from No-Code screens on your end. It’s as straightforward as supplying a single delegate to Qonversion No-Codes prior to showing the screen.
Integrating Qonversion No-Codes with your own purchasing infrastructure necessitates:
- creating a product within the Qonversion dashboard and associating it with a purchase action on your screen,
- implementing and providing a
PurchaseDelegateto Qonversion No-Codes that is responsible for managing purchase and restore requests from No-Code screens.
Unity warningOn Android, when a No-Codes screen is displayed, Unity's game loop is paused because the No-Codes screen runs as a separate Activity on top of Unity's Activity. This means that this delegate will only work on iOS, and will not work on Android.
Implementing PurchaseDelegate
PurchaseDelegateTo handle purchase and restore requests from No-Code screens on your end, you should implement PurchaseDelegate. It has two simple methods - purchase, accepting the requested product, and restore.
extension MyPurchaseHandler: NoCodesPurchaseDelegate {
func purchase(product: Qonversion.Product) async throws {
// Execute the purchase as you wish here
// You can throw exceptions in case of errors
}
func restore() async throws {
// Execute the restore as you wish here
// You can throw exceptions in case of errors
}
}// You can use either coroutine interface as follows:
class MyPurchasesHandler : PurchaseDelegate {
override suspend fun purchase(product: QProduct) {
// Execute the purchase as you wish here
// You can throw exceptions in case of errors
}
override suspend fun restore() {
// Execute the restore as you wish here
// You can throw exceptions in case of errors
}
}
// Or you can use callbacks interface:
class MyPurchaseHandler : PurchaseDelegateWithCallbacks {
override fun purchase(
product: QProduct,
onSuccess: PurchaseDelegateWithCallbacks.OnSuccess,
onError: PurchaseDelegateWithCallbacks.OnError
) {
// Execute the purchase as you wish here
// And call onSuccess once everything is done to close the No-Code screen
onSuccess()
// Call onError with exception in case of error.
}
override fun restore(
onSuccess: PurchaseDelegateWithCallbacks.OnSuccess,
onError: PurchaseDelegateWithCallbacks.OnError
) {
// Execute the restore as you wish here
// And call onSuccess once everything is done to close the No-Code screen
onSuccess()
// Call onError with exception in case of error.
}
}class MyPurchasesHandler implements PurchaseDelegateWithCallbacks {
@Override
public void purchase(@NonNull QProduct product, @NonNull OnSuccess onSuccess, @NonNull OnError onError) {
// Execute the purchase as you wish here
// And call onSuccess once everything is done to close the No-Code screen
onSuccess.invoke();
// Call onError with exception in case of error.
}
@Override
public void restore(@NonNull OnSuccess onSuccess, @NonNull OnError onError) {
// Execute the restore as you wish here
// And call onSuccess once everything is done to close the No-Code screen
onSuccess.invoke()
// Call onError with exception in case of error.
}
}class MyPurchaseDelegate implements PurchaseDelegate {
async purchase(product: Product): Promise<void> {
// Execute the purchase as you wish here
// You can throw exceptions in case of errors
}
async restore(): Promise<void> {
// Execute the restore as you wish here
// You can throw exceptions in case of errors
}
}class MyPurchaseDelegate implements NoCodesPurchaseDelegate {
@override
Future<void> purchase(QProduct product) async {
// Execute the purchase as you wish here
// You can throw exceptions in case of errors
}
@override
Future<void> restore() async {
// Execute the restore as you wish here
// You can throw exceptions in case of errors
}
}public class MyPurchaseDelegate : NoCodesPurchaseDelegate
{
public void Purchase(Product product, System.Action onSuccess, System.Action<string> onError)
{
// Execute the purchase as you wish here
// Call onSuccess() when purchase completes successfully
// Call onError("error message") in case of errors
try
{
// Your purchase logic here
onSuccess();
}
catch (System.Exception e)
{
onError(e.Message);
}
}
public void Restore(System.Action onSuccess, System.Action<string> onError)
{
// Execute the restore as you wish here
// Call onSuccess() when restore completes successfully
// Call onError("error message") in case of errors
try
{
// Your restore logic here
onSuccess();
}
catch (System.Exception e)
{
onError(e.Message);
}
}
}class MyPurchaseDelegate implements Qonversion.PurchaseDelegate {
async purchase(product: Qonversion.Product): Promise<void> {
// Execute the purchase as you wish here
// You can throw exceptions in case of errors
}
async restore(): Promise<void> {
// Execute the restore as you wish here
// You can throw exceptions in case of errors
}
}class MyPurchaseDelegate implements PurchaseDelegate {
async purchase(product: Product): Promise<void> {
// Execute the purchase as you wish here
// You can throw exceptions in case of errors
}
async restore(): Promise<void> {
// Execute the restore as you wish here
// You can throw exceptions in case of errors
}
}Providing PurchaseDelegate
PurchaseDelegateOnce you've implemented the PurchaseDelegate, you need to provide it to Qonversion No-Codes. There are two equal ways to do it - during the initialization via configuration or after - via the No-Codes method.
// Providing during the initialization
let purchaseDelegate = MyPurchaseHandler()
let configuration = NoCodesConfiguration(projectKey: "projectKey", purchaseDelegate: purchaseDelegate)
NoCodes.initialize(with: configuration)
// Or after initialization
let purchaseDelegate = MyPurchaseHandler()
NoCodes.shared.set(purchaseDelegate: purchaseDelegate)// Providing during the initialization
val purchaseDelegate = MyPurchaseHandler()
val noCodesConfig = NoCodesConfig.Builder(this, "projectKey")
.setPurchaseDelegate(purchaseDelegate)
.build()
NoCodes.initialize(noCodesConfig)
// Or after initialization
val purchaseDelegate = MyPurchaseHandler()
NoCodes.shared.setPurchaseDelegate(purchaseDelegate)// Providing during the initialization
final PurchaseDelegateWithCallbacks purchaseDelegate = new MyPurchaseHandler();
final NoCodesConfig noCodesConfig = new NoCodesConfig.Builder(this, "projectKey")
.setPurchaseDelegate(purchaseDelegate)
.build();
NoCodes.initialize(noCodesConfig);
// Or after initialization
final PurchaseDelegateWithCallbacks purchaseDelegate = new MyPurchaseHandler();
NoCodes.getSharedInstance().setPurchaseDelegate(purchaseDelegate);// Providing during the initialization
const purchaseDelegate = MyPurchaseHandler()
const noCodesConfig = new NoCodesConfigBuilder('projectKey')
.setPurchaseDelegate(purchaseDelegate)
.build();
NoCodes.initialize(noCodesConfig);
// Or after initialization
const purchaseDelegate = MyPurchaseHandler()
NoCodes.getSharedInstance().setPurchaseDelegate(purchaseDelegate);// Providing during the initialization
final purchaseDelegate = MyPurchaseDelegate();
final noCodesConfig = NoCodesConfigBuilder('projectKey')
.setPurchaseDelegate(purchaseDelegate)
.build();
NoCodes.initialize(noCodesConfig);
// Or after initialization
final purchaseDelegate = MyPurchaseDelegate();
await NoCodes.getSharedInstance().setPurchaseDelegate(purchaseDelegate);// Providing during the initialization
var purchaseDelegate = new MyPurchaseDelegate();
var noCodesConfig = new NoCodesConfigBuilder("projectKey")
.SetPurchaseDelegate(purchaseDelegate)
.Build();
NoCodes.Initialize(noCodesConfig);
// Or after initialization
var purchaseDelegate = new MyPurchaseDelegate();
NoCodes.GetSharedInstance().SetPurchaseDelegate(purchaseDelegate);// Providing during the initialization
const purchaseDelegate = MyPurchaseHandler()
const noCodesConfig = new Qonversion.NoCodesConfigBuilder('projectKey')
.setPurchaseDelegate(purchaseDelegate)
.build();
Qonversion.NoCodes.initialize(noCodesConfig);
// Or after initialization
const purchaseDelegate = MyPurchaseHandler()
Qonversion.NoCodes.getSharedInstance().setPurchaseDelegate(purchaseDelegate);// Providing during the initialization
const purchaseDelegate = MyPurchaseHandler()
const noCodesConfig = new NoCodesConfigBuilder('projectKey')
.setPurchaseDelegate(purchaseDelegate)
.build();
NoCodes.initialize(noCodesConfig);
// Or after initialization
const purchaseDelegate = MyPurchaseHandler()
NoCodes.getSharedInstance().setPurchaseDelegate(purchaseDelegate);Availability
The described feature is available in the following SDK versions
| Platform | SDK version |
|---|---|
| iOS | 6.1.0+ |
| Android | No-Codes 1.2.1+ |
| React Native | 10.1.0+ |
| Flutter | 11.1.0+ |
| Unity | 9.0.0+ |
| Cordova | 7.0.0+ |
| Capacitor | 1.0.0+ |
Updated 6 days ago
