iOS Question In-App Subscription Question

Yvon Steinthal

Active Member
Licensed User
Hello,

I have a subscription as an in-App purchase for my app. This subscription allows for ads to be completely removed from my app. And i keep a Database with various information about the user including his/her subscription (isMember or Not)

The buying part seems to be ok and working:

B4X:
Sub Subscription_Click
If MyStore.CanMakePayments  And Not(Main.isMember) Then
MyStore.RequestPayment("productid")
End if
End Sub

Sub MyStore_PurchaseCompleted (Success As Boolean, Product As Purchase)
 
    Log("Purchase completed")
    If Product.IsInitialized Then
        Log("Product: " & Product.ProductIdentifier & ", date=" & DateTime.Time(Product.TransactionDate) & _
       ", Transaction identifier=" & Product.TransactionIdentifier)
  
    End If
    Log("Success = " & Success)
 
    If(Success)Then
       'Update my Database to toggle membership status on the user
    End If
 
End Sub

My question is. Once that is done. If he closes the app, how do i know if his/her subscription still is purchased 3 days later? I need to update my Database and start showing ads again.

In other words, is there a way for me to check product validity directly to Apple so i can set his App Status to "showing ads" or "showing no ads"...

Thanks

Y.
 

Yvon Steinthal

Active Member
Licensed User
Thanks Erel, i think the second option is the better, it needs to be a background check up.
I am just unclear as to how to GET the "receipt"... is it part of my Product object in the sub:

B4X:
Sub MyStore_PurchaseCompleted (Success As Boolean, Product As Purchase)
 
Upvote 0

Yvon Steinthal

Active Member
Licensed User
Thanks Erel, i seem to be able to get a receipt from my sandbox account successfully.
My follow up question is on the server side (i use PHP), i believe i need this receipt info to be part of my url Parameters.
Does a simple byte To string method do the trick?

EDIT: It needs to be sent as a b64 encoded string i believe so i guess i just need to do BytetoB64 instead...
 
Last edited:
Upvote 0

Yvon Steinthal

Active Member
Licensed User
It seems to be working so im sharing my server side php file that im calling from my app.

B4X:
<?php

//Base64 receipt from last purchase 
$json['receipt-data'] = $_GET['receipt'];

//Auto generated password from iTunes because this is for an auto-renewable in-app purchase
$json['password'] = "password";

//Additional parameter to verify which url to use (production/debug)
$testing = $_GET['calltype'];

$url = "";

if($testing == 'prod'){
    $url = "https://buy.itunes.apple.com/verifyReceipt";
}else if($testing == 'debug'){
    $url = "https://sandbox.itunes.apple.com/verifyReceipt";
}

$post = json_encode($json);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_POST,1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
$result=curl_exec ($ch);

curl_close ($ch);

echo($result);

?>

Maybe this can help someone...


Y.
 
Upvote 0

Yvon Steinthal

Active Member
Licensed User
I would like to add a little something i discovered that seems to be very useful when testing auto-renewable subscriptions in the sandbox environment:

It is somewhat annoying that this isn't documented anywhere in the developer documentation - only in the iTunes Connect documentation. For convenience I've posted the actual 'real world' to sandbox times below:

  • 1 week = 3 minutes
  • 1 month = 5 minutes
  • 2 months = 10 minutes
  • 3 months = 15 minutes
  • 6 months = 30 minutes
  • 1 year = 1 hour

source: https://stackoverflow.com/a/8825549
 
Upvote 0

Filippo

Expert
Licensed User
It seems to be working so im sharing my server side php file that im calling from my app.

B4X:
<?php

//Base64 receipt from last purchase
$json['receipt-data'] = $_GET['receipt'];

//Auto generated password from iTunes because this is for an auto-renewable in-app purchase
$json['password'] = "password";

//Additional parameter to verify which url to use (production/debug)
$testing = $_GET['calltype'];

$url = "";

if($testing == 'prod'){
    $url = "https://buy.itunes.apple.com/verifyReceipt";
}else if($testing == 'debug'){
    $url = "https://sandbox.itunes.apple.com/verifyReceipt";
}

$post = json_encode($json);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_POST,1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
$result=curl_exec ($ch);

curl_close ($ch);

echo($result);

?>

Maybe this can help someone...


Y.


Hi @Yvon Steinthal ,

can you tell me how to call your PHP script and with which parameters?
 
Upvote 0

Yvon Steinthal

Active Member
Licensed User
Hi Filippo,

Sadly its the weekend and im not at work currently so i cant tell you the exact code. However calling a php script is easy by just calling an HttpJob with your script such as: www.yoursite.com/verifyreceipt.php?arg1=arg1value&arg2=arg2value...

The receipt argument is generated when the user buys the product and triggers the PurchaseCompleted event. I just save the receipt locally in order to call my « verifyreceipt.php » script everytime the app is launched.

The password one is generated in your Itunes account in relation to your in-app purchase product. Look around you can generate it easily.

Lastly my calltype argument is just to be able to switch from sandbox environment to production easily while debugging. I highly suggest allowing sandbox testers from iTunes.

Hope this helps until i get back to work on monday!

Y.
 
Upvote 0

Filippo

Expert
Licensed User
Upvote 0

Yvon Steinthal

Active Member
Licensed User
I hope this helps: But im using a Restore Transaction Button

B4X:
Sub Restore_Click
    isBuying = False
    If(MyStore.CanMakePayments)Then
        MyStore.RestoreTransactions
'This will fire PurchaseCompleted or/and TransactionRestored
    Else
        Dim hd As HUD
        hd.ToastMessageShow(Main.t.Trans("Unavailable on this device"),True)
    End If
   
End Sub

Sub MyStore_TransactionsRestored (Success As Boolean)
   
    Log("Transaction Restored:"&Success)

    If(Success)Then
        Msgbox2("RestoredTrans","Transaction Restored","Membership",Array("OK"))
        Main.isMember = True
        'Change to my server the value of membership for this user
    Else
        Msgbox2("RestoredTrans2","No Membership Purchased","Membership",Array("OK"))
    End If
   
End Sub
 
Upvote 0

Filippo

Expert
Licensed User
I hope this helps: But im using a Restore Transaction Button
Hi @Yvon Steinthal,

Thank you for your help, but unfortunately your code for "Subscription without automatic renewal" does not work.
I have now implemented my own user registration system.
 
Upvote 0
Top