improve android payments
GodotPaymentV3 currently consumes purchased item right after purchasing. But, some in-app item should not consume like "remove ads permanently" So, I added "setAutoConsume(boolean)", "requestPurchased()", "consume(sku_string)". AutoConsume is true by default as before. usage: func _ready(): var payment = Globals.get_singleton("GodotPayments") payment.setPurchaseCallbackId(get_instance_ID()) payment.setAutoConsume(false) # default : true payment.requestPurchased() # callback : has_purchased payment.purchase("item_name") # callback : purchase_success, purchase_fail, purchase_cancel, purchase_owned payment.consume("item_name") # callback : consume_success func purchase_success(receipt, signature, sku): print("purchase_success : ", sku) func purchase_fail(): print("purchase_fail") func purchase_cancel(): print("purchase_cancel") func purchase_owned(sku): print("purchase_owned : ", sku) func consume_success(receipt, signature, sku): print("consume_success : ", sku) func has_purchased(receipt, signature, sku): if sku == "": print("has_purchased : nothing") else: print("has_purchased : ", sku)
This commit is contained in:
parent
bd736e5af2
commit
3fbaa479e3
|
@ -27,7 +27,7 @@ public class GodotPaymentV3 extends Godot.SingletonBase {
|
|||
activity.getPaymentsManager().requestPurchase(sku, transactionId);
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
/* public string requestPurchasedTicket(){
|
||||
activity.getPaymentsManager()
|
||||
|
@ -42,7 +42,7 @@ public class GodotPaymentV3 extends Godot.SingletonBase {
|
|||
|
||||
public GodotPaymentV3(Activity p_activity) {
|
||||
|
||||
registerClass("GodotPayments", new String[] {"purchase", "setPurchaseCallbackId", "setPurchaseValidationUrlPrefix", "setTransactionId", "getSignature", "consumeUnconsumedPurchases"});
|
||||
registerClass("GodotPayments", new String[] {"purchase", "setPurchaseCallbackId", "setPurchaseValidationUrlPrefix", "setTransactionId", "getSignature", "consumeUnconsumedPurchases", "requestPurchased", "setAutoConsume", "consume"});
|
||||
activity=(Godot) p_activity;
|
||||
}
|
||||
|
||||
|
@ -54,7 +54,6 @@ public class GodotPaymentV3 extends Godot.SingletonBase {
|
|||
activity.getPaymentsManager().consumeUnconsumedPurchases();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private String signature;
|
||||
|
@ -63,25 +62,26 @@ public class GodotPaymentV3 extends Godot.SingletonBase {
|
|||
}
|
||||
|
||||
|
||||
public void callbackSuccess(String ticket, String signature){
|
||||
// Log.d(this.getClass().getName(), "PRE-Send callback to purchase success");
|
||||
GodotLib.callobject(purchaseCallbackId, "purchase_success", new Object[]{ticket, signature});
|
||||
// Log.d(this.getClass().getName(), "POST-Send callback to purchase success");
|
||||
public void callbackSuccess(String ticket, String signature, String sku){
|
||||
// Log.d(this.getClass().getName(), "PRE-Send callback to purchase success");
|
||||
GodotLib.callobject(purchaseCallbackId, "purchase_success", new Object[]{ticket, signature, sku});
|
||||
// Log.d(this.getClass().getName(), "POST-Send callback to purchase success");
|
||||
}
|
||||
|
||||
public void callbackSuccessProductMassConsumed(String ticket, String signature, String sku){
|
||||
// Log.d(this.getClass().getName(), "PRE-Send callback to consume success");
|
||||
GodotLib.calldeferred(purchaseCallbackId, "consume_success", new Object[]{ticket, signature, sku});
|
||||
// Log.d(this.getClass().getName(), "POST-Send callback to consume success");
|
||||
// Log.d(this.getClass().getName(), "PRE-Send callback to consume success");
|
||||
Log.d(this.getClass().getName(), "callbackSuccessProductMassConsumed > "+ticket+","+signature+","+sku);
|
||||
GodotLib.calldeferred(purchaseCallbackId, "consume_success", new Object[]{ticket, signature, sku});
|
||||
// Log.d(this.getClass().getName(), "POST-Send callback to consume success");
|
||||
}
|
||||
|
||||
public void callbackSuccessNoUnconsumedPurchases(){
|
||||
GodotLib.calldeferred(purchaseCallbackId, "no_validation_required", new Object[]{});
|
||||
GodotLib.calldeferred(purchaseCallbackId, "no_validation_required", new Object[]{});
|
||||
}
|
||||
|
||||
public void callbackFail(){
|
||||
GodotLib.calldeferred(purchaseCallbackId, "purchase_fail", new Object[]{});
|
||||
// GodotLib.callobject(purchaseCallbackId, "purchase_fail", new Object[]{});
|
||||
GodotLib.calldeferred(purchaseCallbackId, "purchase_fail", new Object[]{});
|
||||
// GodotLib.callobject(purchaseCallbackId, "purchase_fail", new Object[]{});
|
||||
}
|
||||
|
||||
public void callbackCancel(){
|
||||
|
@ -89,6 +89,10 @@ public class GodotPaymentV3 extends Godot.SingletonBase {
|
|||
// GodotLib.callobject(purchaseCallbackId, "purchase_cancel", new Object[]{});
|
||||
}
|
||||
|
||||
public void callbackAlreadyOwned(String sku){
|
||||
GodotLib.calldeferred(purchaseCallbackId, "purchase_owned", new Object[]{sku});
|
||||
}
|
||||
|
||||
public int getPurchaseCallbackId() {
|
||||
return purchaseCallbackId;
|
||||
}
|
||||
|
@ -97,8 +101,6 @@ public class GodotPaymentV3 extends Godot.SingletonBase {
|
|||
this.purchaseCallbackId = purchaseCallbackId;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public String getPurchaseValidationUrlPrefix(){
|
||||
return this.purchaseValidationUrlPrefix ;
|
||||
}
|
||||
|
@ -107,12 +109,10 @@ public class GodotPaymentV3 extends Godot.SingletonBase {
|
|||
this.purchaseValidationUrlPrefix = url;
|
||||
}
|
||||
|
||||
|
||||
public String getAccessToken() {
|
||||
return accessToken;
|
||||
}
|
||||
|
||||
|
||||
public void setAccessToken(String accessToken) {
|
||||
this.accessToken = accessToken;
|
||||
}
|
||||
|
@ -125,4 +125,30 @@ public class GodotPaymentV3 extends Godot.SingletonBase {
|
|||
return this.transactionId;
|
||||
}
|
||||
|
||||
// request purchased items are not consumed
|
||||
public void requestPurchased(){
|
||||
activity.getPaymentsManager().setBaseSingleton(this);
|
||||
activity.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
activity.getPaymentsManager().requestPurchased();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// callback for requestPurchased()
|
||||
public void callbackPurchased(String receipt, String signature, String sku){
|
||||
GodotLib.calldeferred(purchaseCallbackId, "has_purchased", new Object[]{receipt, signature, sku});
|
||||
}
|
||||
|
||||
// consume item automatically after purchase. default is true.
|
||||
public void setAutoConsume(boolean autoConsume){
|
||||
activity.getPaymentsManager().setAutoConsume(autoConsume);
|
||||
}
|
||||
|
||||
// consume a specific item
|
||||
public void consume(String sku){
|
||||
activity.getPaymentsManager().consume(sku);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,10 +25,8 @@ import com.android.vending.billing.IInAppBillingService;
|
|||
public class PaymentsManager {
|
||||
|
||||
public static final int BILLING_RESPONSE_RESULT_OK = 0;
|
||||
|
||||
|
||||
public static final int REQUEST_CODE_FOR_PURCHASE = 0x1001;
|
||||
|
||||
private static boolean auto_consume = true;
|
||||
|
||||
private Activity activity;
|
||||
IInAppBillingService mService;
|
||||
|
@ -69,13 +67,12 @@ public class PaymentsManager {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onServiceConnected(ComponentName name,
|
||||
IBinder service) {
|
||||
mService = IInAppBillingService.Stub.asInterface(service);
|
||||
public void onServiceConnected(ComponentName name, IBinder service) {
|
||||
mService = IInAppBillingService.Stub.asInterface(service);
|
||||
}
|
||||
};
|
||||
|
||||
public void requestPurchase(String sku, String transactionId){
|
||||
public void requestPurchase(final String sku, String transactionId){
|
||||
new PurchaseTask(mService, Godot.getInstance()) {
|
||||
|
||||
@Override
|
||||
|
@ -88,6 +85,12 @@ public class PaymentsManager {
|
|||
protected void canceled() {
|
||||
godotPaymentV3.callbackCancel();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void alreadyOwned() {
|
||||
godotPaymentV3.callbackAlreadyOwned(sku);
|
||||
}
|
||||
|
||||
}.purchase(sku, transactionId);
|
||||
|
||||
}
|
||||
|
@ -114,26 +117,82 @@ public class PaymentsManager {
|
|||
}.consumeItAll();
|
||||
}
|
||||
|
||||
public void requestPurchased(){
|
||||
try{
|
||||
PaymentsCache pc = new PaymentsCache(Godot.getInstance());
|
||||
|
||||
// Log.d("godot", "requestPurchased for " + activity.getPackageName());
|
||||
Bundle bundle = mService.getPurchases(3, activity.getPackageName(), "inapp",null);
|
||||
|
||||
/*
|
||||
for (String key : bundle.keySet()) {
|
||||
Object value = bundle.get(key);
|
||||
Log.d("godot", String.format("%s %s (%s)", key, value.toString(), value.getClass().getName()));
|
||||
}
|
||||
*/
|
||||
|
||||
if (bundle.getInt("RESPONSE_CODE") == 0){
|
||||
|
||||
final ArrayList<String> myPurchases = bundle.getStringArrayList("INAPP_PURCHASE_DATA_LIST");
|
||||
final ArrayList<String> mySignatures = bundle.getStringArrayList("INAPP_DATA_SIGNATURE_LIST");
|
||||
|
||||
|
||||
if (myPurchases == null || myPurchases.size() == 0){
|
||||
// Log.d("godot", "No purchases!");
|
||||
godotPaymentV3.callbackPurchased("", "", "");
|
||||
return;
|
||||
}
|
||||
|
||||
// Log.d("godot", "# products are purchased:" + myPurchases.size());
|
||||
for (int i=0;i<myPurchases.size();i++)
|
||||
{
|
||||
|
||||
try{
|
||||
String receipt = myPurchases.get(i);
|
||||
JSONObject inappPurchaseData = new JSONObject(receipt);
|
||||
String sku = inappPurchaseData.getString("productId");
|
||||
String token = inappPurchaseData.getString("purchaseToken");
|
||||
String signature = mySignatures.get(i);
|
||||
// Log.d("godot", "purchased item:" + token + "\n" + receipt);
|
||||
|
||||
pc.setConsumableValue("ticket_signautre", sku, signature);
|
||||
pc.setConsumableValue("ticket", sku, receipt);
|
||||
pc.setConsumableFlag("block", sku, true);
|
||||
pc.setConsumableValue("token", sku, token);
|
||||
|
||||
godotPaymentV3.callbackPurchased(receipt, signature, sku);
|
||||
} catch (JSONException e) {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}catch(Exception e){
|
||||
Log.d("godot", "Error requesting purchased products:" + e.getClass().getName() + ":" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void processPurchaseResponse(int resultCode, Intent data) {
|
||||
new HandlePurchaseTask(activity){
|
||||
|
||||
@Override
|
||||
protected void success(final String sku, final String signature, final String ticket) {
|
||||
godotPaymentV3.callbackSuccess(ticket, signature);
|
||||
new ConsumeTask(mService, activity) {
|
||||
godotPaymentV3.callbackSuccess(ticket, signature, sku);
|
||||
|
||||
@Override
|
||||
protected void success(String ticket) {
|
||||
// godotPaymentV3.callbackSuccess("");
|
||||
}
|
||||
if (auto_consume){
|
||||
new ConsumeTask(mService, activity) {
|
||||
|
||||
@Override
|
||||
protected void error(String message) {
|
||||
godotPaymentV3.callbackFail();
|
||||
@Override
|
||||
protected void success(String ticket) {
|
||||
// godotPaymentV3.callbackSuccess("");
|
||||
}
|
||||
|
||||
}
|
||||
}.consume(sku);
|
||||
@Override
|
||||
protected void error(String message) {
|
||||
godotPaymentV3.callbackFail();
|
||||
|
||||
}
|
||||
}.consume(sku);
|
||||
}
|
||||
|
||||
// godotPaymentV3.callbackSuccess(new PaymentsCache(activity).getConsumableValue("ticket", sku),signature);
|
||||
// godotPaymentV3.callbackSuccess(ticket);
|
||||
|
@ -151,7 +210,7 @@ public class PaymentsManager {
|
|||
godotPaymentV3.callbackCancel();
|
||||
|
||||
}
|
||||
}.handlePurchaseRequest(resultCode, data);
|
||||
}.handlePurchaseRequest(resultCode, data);
|
||||
}
|
||||
|
||||
public void validatePurchase(String purchaseToken, final String sku){
|
||||
|
@ -165,7 +224,7 @@ public class PaymentsManager {
|
|||
|
||||
@Override
|
||||
protected void success(String ticket) {
|
||||
godotPaymentV3.callbackSuccess(ticket, null);
|
||||
godotPaymentV3.callbackSuccess(ticket, null, sku);
|
||||
|
||||
}
|
||||
|
||||
|
@ -192,11 +251,31 @@ public class PaymentsManager {
|
|||
}.validatePurchase(sku);
|
||||
}
|
||||
|
||||
public void setAutoConsume(boolean autoConsume){
|
||||
auto_consume = autoConsume;
|
||||
}
|
||||
|
||||
public void consume(final String sku){
|
||||
new ConsumeTask(mService, activity) {
|
||||
|
||||
@Override
|
||||
protected void success(String ticket) {
|
||||
godotPaymentV3.callbackSuccessProductMassConsumed(ticket, "", sku);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void error(String message) {
|
||||
godotPaymentV3.callbackFail();
|
||||
|
||||
}
|
||||
}.consume(sku);
|
||||
}
|
||||
|
||||
private GodotPaymentV3 godotPaymentV3;
|
||||
|
||||
public void setBaseSingleton(GodotPaymentV3 godotPaymentV3) {
|
||||
this.godotPaymentV3 = godotPaymentV3;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -62,7 +62,11 @@ abstract public class PurchaseTask {
|
|||
// Log.d("XXX", "Buy intent response code: " + responseCode);
|
||||
if(responseCode == 1 || responseCode == 3 || responseCode == 4){
|
||||
canceled();
|
||||
return ;
|
||||
return;
|
||||
}
|
||||
if(responseCode == 7){
|
||||
alreadyOwned();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
@ -92,6 +96,6 @@ abstract public class PurchaseTask {
|
|||
|
||||
abstract protected void error(String message);
|
||||
abstract protected void canceled();
|
||||
|
||||
abstract protected void alreadyOwned();
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue