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)
 

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:

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.
 

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
 

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?
 

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.
 

Filippo

Expert
Licensed User

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
 

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.
 

Yvon Steinthal

Active Member
Licensed User
Oh im sorry, my solution is WITH automatic renewal!
I didnt know that you were implementing a non-automatic renewal purchase.
 
Top