sjbillingclient 0.2.2__py3-none-any.whl → 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- sjbillingclient/jclass/accountidentifiers.py +10 -0
- sjbillingclient/jclass/acknowledge.py +1 -1
- sjbillingclient/jclass/billing.py +58 -18
- sjbillingclient/jclass/consume.py +1 -1
- sjbillingclient/jclass/purchase.py +42 -4
- sjbillingclient/jclass/queryproduct.py +19 -4
- sjbillingclient/jclass/querypurchases.py +14 -0
- sjbillingclient/jinterface/purchases.py +13 -1
- sjbillingclient/tools/__init__.py +77 -9
- {sjbillingclient-0.2.2.dist-info → sjbillingclient-1.0.0.dist-info}/METADATA +125 -7
- sjbillingclient-1.0.0.dist-info/RECORD +19 -0
- sjbillingclient-0.2.2.dist-info/RECORD +0 -17
- {sjbillingclient-0.2.2.dist-info → sjbillingclient-1.0.0.dist-info}/WHEEL +0 -0
@@ -0,0 +1,10 @@
|
|
1
|
+
from jnius import JavaClass, MetaJavaClass, JavaMethod
|
2
|
+
|
3
|
+
__all__ = ("AccountIdentifiers",)
|
4
|
+
|
5
|
+
|
6
|
+
class AccountIdentifiers(JavaClass, metaclass=MetaJavaClass):
|
7
|
+
__javaclass__ = "com/android/billingclient/api/AccountIdentifiers"
|
8
|
+
|
9
|
+
getObfuscatedAccountId = JavaMethod("()Ljava/lang/String;")
|
10
|
+
getObfuscatedProfileId = JavaMethod("()Ljava/lang/String;")
|
@@ -4,5 +4,5 @@ __all__ = ("AcknowledgePurchaseParams",)
|
|
4
4
|
|
5
5
|
|
6
6
|
class AcknowledgePurchaseParams(JavaClass, metaclass=MetaJavaClass):
|
7
|
-
__javaclass__ =
|
7
|
+
__javaclass__ = "com/android/billingclient/api/AcknowledgePurchaseParams"
|
8
8
|
newBuilder = JavaStaticMethod("()Lcom/android/billingclient/api/AcknowledgePurchaseParams$Builder;")
|
@@ -1,7 +1,8 @@
|
|
1
1
|
from jnius import JavaClass, MetaJavaClass, JavaStaticMethod, JavaStaticField, JavaMethod, JavaMultipleMethod
|
2
2
|
|
3
|
-
__all__ = ("BillingClient", "BillingFlowParams", "ProductType", "GetBillingConfigParams",
|
4
|
-
"ProductDetailsParams", "BillingResponseCode"
|
3
|
+
__all__ = ("BillingClient", "BillingFlowParams", "BillingFlowParamsBuilder", "ProductType", "GetBillingConfigParams",
|
4
|
+
"ProductDetailsParams", "BillingResponseCode", "SubscriptionUpdateParams", "SubscriptionUpdateParamsBuilder",
|
5
|
+
"ReplacementMode")
|
5
6
|
|
6
7
|
|
7
8
|
class BillingClient(JavaClass, metaclass=MetaJavaClass):
|
@@ -54,27 +55,28 @@ class BillingClient(JavaClass, metaclass=MetaJavaClass):
|
|
54
55
|
"(Lcom/android/billingclient/api/QueryProductDetailsParams;"
|
55
56
|
"Lcom/android/billingclient/api/ProductDetailsResponseListener;)V"
|
56
57
|
)
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
False, False),
|
61
|
-
("(Ljava/lang/String;Lcom/android/billingclient/api/PurchaseHistoryResponseListener;)V,",
|
62
|
-
False, False),
|
63
|
-
])
|
64
|
-
queryPurchasesAsync = JavaMultipleMethod([
|
65
|
-
("(Lcom/android/billingclient/api/QueryPurchasesParams;"
|
66
|
-
"Lcom/android/billingclient/api/PurchasesResponseListener;)V", False, False),
|
67
|
-
("(Ljava/lang/String;Lcom/android/billingclient/api/PurchasesResponseListener;)V",
|
68
|
-
False, False),
|
69
|
-
])
|
70
|
-
querySkuDetailsAsync = JavaMethod(
|
71
|
-
"(Lcom/android/billingclient/api/SkuDetailsParams;"
|
72
|
-
"Lcom/android/billingclient/api/SkuDetailsResponseListener;)V"
|
58
|
+
queryPurchasesAsync = JavaMethod(
|
59
|
+
"(Lcom/android/billingclient/api/QueryPurchasesParams;"
|
60
|
+
"Lcom/android/billingclient/api/PurchasesResponseListener;)V"
|
73
61
|
)
|
74
62
|
startConnection = JavaMethod("(Lcom/android/billingclient/api/BillingClientStateListener;)V")
|
75
63
|
isReady = JavaMethod("()Z")
|
76
64
|
|
77
65
|
|
66
|
+
class BillingClientBuilder(JavaClass, metaclass=MetaJavaClass):
|
67
|
+
__javaclass__ = "com/android/billingclient/api/BillingClient$Builder"
|
68
|
+
build = JavaMethod("()Lcom/android/billingclient/api/BillingClient;")
|
69
|
+
enableAlternativeBillingOnly = JavaMethod("()Lcom/android/billingclient/api/BillingClient$Builder;")
|
70
|
+
enableAutoServiceReconnection = JavaMethod("()Lcom/android/billingclient/api/BillingClient$Builder;")
|
71
|
+
enableExternalOffer = JavaMethod("()Lcom/android/billingclient/api/BillingClient$Builder;")
|
72
|
+
enablePendingPurchases = JavaMethod("(Lcom/android/billingclient/api/PendingPurchasesParams;)"
|
73
|
+
"Lcom/android/billingclient/api/BillingClient$Builder;")
|
74
|
+
enableUserChoiceBilling = JavaMethod("(Lcom/android/billingclient/api/UserChoiceBillingListener;)"
|
75
|
+
"Lcom/android/billingclient/api/BillingClient$Builder;")
|
76
|
+
setListener = JavaMethod("(Lcom/android/billingclient/api/PurchasesUpdatedListener;)"
|
77
|
+
"Lcom/android/billingclient/api/BillingClient$Builder;")
|
78
|
+
|
79
|
+
|
78
80
|
class ProductType(JavaClass, metaclass=MetaJavaClass):
|
79
81
|
__javaclass__ = "com/android/billingclient/api/BillingClient$ProductType"
|
80
82
|
INAPP = JavaStaticField("Ljava/lang/String;")
|
@@ -102,6 +104,19 @@ class BillingFlowParams(JavaClass, metaclass=MetaJavaClass):
|
|
102
104
|
newBuilder = JavaStaticMethod("()Lcom/android/billingclient/api/BillingFlowParams$Builder;")
|
103
105
|
|
104
106
|
|
107
|
+
class BillingFlowParamsBuilder(JavaClass, metaclass=MetaJavaClass):
|
108
|
+
__javaclass__ = "com/android/billingclient/api/BillingFlowParams$Builder"
|
109
|
+
build = JavaMethod("()Lcom/android/billingclient/api/BillingFlowParams;")
|
110
|
+
setIsOfferPersonalized = JavaMethod("(Z)Lcom/android/billingclient/api/BillingFlowParams$Builder;")
|
111
|
+
setObfuscatedAccountId = JavaMethod("(Ljava/lang/String;)Lcom/android/billingclient/api/BillingFlowParams$Builder;")
|
112
|
+
setObfuscatedProfileId = JavaMethod("(Ljava/lang/String;)Lcom/android/billingclient/api/BillingFlowParams$Builder;")
|
113
|
+
setProductDetailsParamsList = JavaMethod("(Ljava/util/List;)Lcom/android/billingclient/api"
|
114
|
+
"/BillingFlowParams$Builder;")
|
115
|
+
setSubscriptionUpdateParams = JavaMethod("(Lcom/android/billingclient/api"
|
116
|
+
"/BillingFlowParams$SubscriptionUpdateParams;)Lcom/android/billingclient"
|
117
|
+
"/api/BillingFlowParams$Builder;")
|
118
|
+
|
119
|
+
|
105
120
|
class GetBillingConfigParams(JavaClass, metaclass=MetaJavaClass):
|
106
121
|
__javaclass__ = "com/android/billingclient/api/GetBillingConfigParams"
|
107
122
|
newBuilder = JavaStaticMethod("()Lcom/android/billingclient/api/GetBillingConfigParams$Builder;")
|
@@ -110,3 +125,28 @@ class GetBillingConfigParams(JavaClass, metaclass=MetaJavaClass):
|
|
110
125
|
class ProductDetailsParams(JavaClass, metaclass=MetaJavaClass):
|
111
126
|
__javaclass__ = "com/android/billingclient/api/BillingFlowParams$ProductDetailsParams"
|
112
127
|
newBuilder = JavaStaticMethod("()Lcom/android/billingclient/api/BillingFlowParams$ProductDetailsParams$Builder;")
|
128
|
+
|
129
|
+
|
130
|
+
class SubscriptionUpdateParams(JavaClass, metaclass=MetaJavaClass):
|
131
|
+
__javaclass__ = "com/android/billingclient/api/BillingFlowParams$SubscriptionUpdateParams"
|
132
|
+
newBuilder = JavaStaticMethod("()Lcom/android/billingclient/api/BillingFlowParams"
|
133
|
+
"$SubscriptionUpdateParams$Builder;")
|
134
|
+
|
135
|
+
|
136
|
+
class SubscriptionUpdateParamsBuilder(JavaClass, metaclass=MetaJavaClass):
|
137
|
+
__javaclass__ = "com/android/billingclient/api/BillingFlowParams$SubscriptionUpdateParams$Builder"
|
138
|
+
build = JavaMethod("()Lcom/android/billingclient/api/BillingFlowParams$SubscriptionUpdateParams;")
|
139
|
+
setOldPurchaseToken = JavaMethod("(Ljava/lang/String;)Lcom/android/billingclient/api"
|
140
|
+
"/BillingFlowParams$SubscriptionUpdateParams$Builder;")
|
141
|
+
setSubscriptionReplacementMode = JavaMethod("(I)Lcom/android/billingclient/api"
|
142
|
+
"/BillingFlowParams$SubscriptionUpdateParams$Builder;")
|
143
|
+
|
144
|
+
|
145
|
+
class ReplacementMode(JavaClass, metaclass=MetaJavaClass):
|
146
|
+
__javaclass__ = "com/android/billingclient/api/BillingFlowParams$SubscriptionUpdateParams$ReplacementMode"
|
147
|
+
CHARGE_FULL_PRICE = JavaStaticField("I")
|
148
|
+
CHARGE_PRORATED_PRICE = JavaStaticField("I")
|
149
|
+
DEFERRED = JavaStaticField("I")
|
150
|
+
UNKNOWN_REPLACEMENT_MODE = JavaStaticField("I")
|
151
|
+
WITHOUT_PRORATION = JavaStaticField("I")
|
152
|
+
WITH_TIME_PRORATION = JavaStaticField("I")
|
@@ -4,5 +4,5 @@ __all__ = ("ConsumeParams",)
|
|
4
4
|
|
5
5
|
|
6
6
|
class ConsumeParams(JavaClass, metaclass=MetaJavaClass):
|
7
|
-
__javaclass__ =
|
7
|
+
__javaclass__ = "com/android/billingclient/api/ConsumeParams"
|
8
8
|
newBuilder = JavaStaticMethod("()Lcom/android/billingclient/api/ConsumeParams$Builder;")
|
@@ -1,16 +1,54 @@
|
|
1
|
-
from jnius import JavaClass, MetaJavaClass, JavaStaticMethod, JavaMethod
|
1
|
+
from jnius import JavaClass, MetaJavaClass, JavaStaticMethod, JavaMethod, JavaStaticField
|
2
2
|
|
3
|
-
__all__ = ("PendingPurchasesParams", "PendingPurchasesParamsBuilder")
|
3
|
+
__all__ = ("PendingPurchasesParams", "PendingPurchasesParamsBuilder", "Purchase", "PurchaseState", "PendingPurchaseUpdate")
|
4
4
|
|
5
5
|
|
6
6
|
class PendingPurchasesParams(JavaClass, metaclass=MetaJavaClass):
|
7
|
-
__javaclass__ =
|
7
|
+
__javaclass__ = "com/android/billingclient/api/PendingPurchasesParams"
|
8
8
|
newBuilder = JavaStaticMethod("()Lcom/android/billingclient/api/PendingPurchasesParams$Builder;")
|
9
9
|
|
10
10
|
|
11
11
|
class PendingPurchasesParamsBuilder(JavaClass, metaclass=MetaJavaClass):
|
12
|
-
__javaclass__ =
|
12
|
+
__javaclass__ = "com/android/billingclient/api/PendingPurchasesParams$Builder"
|
13
13
|
|
14
14
|
build = JavaMethod("()Lcom/android/billingclient/api/PendingPurchasesParams;")
|
15
15
|
enableOneTimeProducts = JavaMethod("()Lcom/android/billingclient/api/PendingPurchasesParams$Builder;")
|
16
16
|
enablePrepaidPlans = JavaMethod("()Lcom/android/billingclient/api/PendingPurchasesParams$Builder;")
|
17
|
+
|
18
|
+
|
19
|
+
class Purchase(JavaClass, metaclass=MetaJavaClass):
|
20
|
+
__javaclass__ = "com/android/billingclient/api/Purchase"
|
21
|
+
|
22
|
+
getAccountIdentifiers = JavaMethod("()Lcom/android/billingclient/api/AccountIdentifiers;")
|
23
|
+
getDeveloperPayload = JavaMethod("()Ljava/lang/String;")
|
24
|
+
getOrderId = JavaMethod("()Ljava/lang/String;")
|
25
|
+
getOriginalJson = JavaMethod("()Ljava/lang/String;")
|
26
|
+
getPackageName = JavaMethod("()Ljava/lang/String;")
|
27
|
+
getPendingPurchaseUpdate = JavaMethod("()Lcom/android/billingclient/api/Purchase$PendingPurchaseUpdate;")
|
28
|
+
getProducts = JavaMethod("()Ljava/util/List;")
|
29
|
+
getPurchaseState = JavaMethod("()I")
|
30
|
+
getPurchaseTime = JavaMethod("()J")
|
31
|
+
getPurchaseToken = JavaMethod("()Ljava/lang/String;")
|
32
|
+
getQuantity = JavaMethod("()I")
|
33
|
+
getSignature = JavaMethod("()Ljava/lang/String;")
|
34
|
+
hashCode = JavaMethod("()I")
|
35
|
+
isAcknowledged = JavaMethod("()Z")
|
36
|
+
isAutoRenewing = JavaMethod("()Z")
|
37
|
+
toString = JavaMethod("()Ljava/lang/String;")
|
38
|
+
|
39
|
+
|
40
|
+
class PurchaseState(JavaClass, metaclass=MetaJavaClass):
|
41
|
+
__javaclass__ = "com/android/billingclient/api/Purchase$PurchaseState"
|
42
|
+
|
43
|
+
# Purchase state constants
|
44
|
+
PENDING = JavaStaticField("I")
|
45
|
+
PURCHASED = JavaStaticField("I")
|
46
|
+
UNSPECIFIED = JavaStaticField("I")
|
47
|
+
|
48
|
+
|
49
|
+
class PendingPurchaseUpdate(JavaClass, metaclass=MetaJavaClass):
|
50
|
+
__javaclass__ = "com/android/billingclient/api/Purchase$PendingPurchaseUpdate"
|
51
|
+
|
52
|
+
getProducts = JavaMethod("()Ljava/util/List;")
|
53
|
+
getPurchaseToken = JavaMethod("()Ljava/lang/String;")
|
54
|
+
|
@@ -1,20 +1,35 @@
|
|
1
1
|
from jnius import JavaClass, MetaJavaClass, JavaStaticMethod, JavaMethod
|
2
2
|
|
3
|
-
__all__ = ("QueryProductDetailsParams", "QueryProductDetailsParamsProduct")
|
3
|
+
__all__ = ("QueryProductDetailsParams", "QueryProductDetailsParamsProduct", "QueryProductDetailsParamsBuilder", "QueryProductDetailsParamsProductBuilder")
|
4
4
|
|
5
5
|
|
6
6
|
class QueryProductDetailsParams(JavaClass, metaclass=MetaJavaClass):
|
7
|
-
__javaclass__ =
|
7
|
+
__javaclass__ = "com/android/billingclient/api/QueryProductDetailsParams"
|
8
8
|
newBuilder = JavaStaticMethod("()Lcom/android/billingclient/api/QueryProductDetailsParams$Builder;")
|
9
9
|
|
10
10
|
|
11
11
|
class QueryProductDetailsParamsProduct(JavaClass, metaclass=MetaJavaClass):
|
12
|
-
__javaclass__ =
|
12
|
+
__javaclass__ = "com/android/billingclient/api/QueryProductDetailsParams$Product"
|
13
13
|
newBuilder = JavaStaticMethod("()Lcom/android/billingclient/api/QueryProductDetailsParams$Product$Builder;")
|
14
14
|
|
15
15
|
|
16
|
+
class QueryProductDetailsParamsProductBuilder(JavaClass, metaclass=MetaJavaClass):
|
17
|
+
__javaclass__ = "com/android/billingclient/api/QueryProductDetailsParams$Product$Builder"
|
18
|
+
build = JavaMethod("()Lcom/android/billingclient/api/QueryProductDetailsParams$Product;")
|
19
|
+
setProductId = JavaMethod("(Ljava/lang/String;)"
|
20
|
+
"Lcom/android/billingclient/api/QueryProductDetailsParams$Product$Builder;")
|
21
|
+
setProductType = JavaMethod("(Ljava/lang/String;)"
|
22
|
+
"Lcom/android/billingclient/api/QueryProductDetailsParams$Product$Builder;")
|
23
|
+
|
24
|
+
|
25
|
+
class QueryProductDetailsParamsBuilder(JavaClass, metaclass=MetaJavaClass):
|
26
|
+
__javaclass__ = "com/android/billingclient/api/QueryProductDetailsParams$Builder"
|
27
|
+
build = JavaMethod("()Lcom/android/billingclient/api/QueryProductDetailsParams;")
|
28
|
+
setProductList = JavaMethod("(Ljava/util/List;)Lcom/android/billingclient/api/QueryProductDetailsParams$Builder;")
|
29
|
+
|
30
|
+
|
16
31
|
class QueryProductDetailsResult(JavaClass, metaclass=MetaJavaClass):
|
17
|
-
__javaclass__ =
|
32
|
+
__javaclass__ = "com/android/billingclient/api/QueryProductDetailsResult"
|
18
33
|
create = JavaStaticMethod("(Ljava/util/List;Ljava/util/List;)"
|
19
34
|
"Lcom/android/billingclient/api/QueryProductDetailsResult;")
|
20
35
|
getProductDetailsList = JavaMethod("()Ljava/util/List;")
|
@@ -0,0 +1,14 @@
|
|
1
|
+
from jnius import JavaClass, MetaJavaClass, JavaStaticMethod, JavaMethod
|
2
|
+
|
3
|
+
__all__ = ("QueryPurchasesParams", "QueryPurchasesParamsBuilder")
|
4
|
+
|
5
|
+
|
6
|
+
class QueryPurchasesParams(JavaClass, metaclass=MetaJavaClass):
|
7
|
+
__javaclass__ = "com/android/billingclient/api/QueryPurchasesParams"
|
8
|
+
newBuilder = JavaStaticMethod("()Lcom/android/billingclient/api/QueryPurchasesParams$Builder;")
|
9
|
+
|
10
|
+
|
11
|
+
class QueryPurchasesParamsBuilder(JavaClass, metaclass=MetaJavaClass):
|
12
|
+
__javaclass__ = "com/android/billingclient/api/QueryPurchasesParams$Builder"
|
13
|
+
build = JavaMethod("()Lcom/android/billingclient/api/QueryPurchasesParams;")
|
14
|
+
setProductType = JavaMethod("(Ljava/lang/String;)Lcom/android/billingclient/api/QueryPurchasesParams$Builder;")
|
@@ -1,4 +1,4 @@
|
|
1
|
-
__all__ = ("PurchasesUpdatedListener", )
|
1
|
+
__all__ = ("PurchasesUpdatedListener", "PurchasesResponseListener")
|
2
2
|
|
3
3
|
from jnius import PythonJavaClass, java_method
|
4
4
|
from sjbillingclient import is_jnull
|
@@ -14,3 +14,15 @@ class PurchasesUpdatedListener(PythonJavaClass):
|
|
14
14
|
@java_method("(Lcom/android/billingclient/api/BillingResult;Ljava/util/List;)V")
|
15
15
|
def onPurchasesUpdated(self, billing_result, purchases):
|
16
16
|
self.callback(billing_result, is_jnull(purchases), purchases)
|
17
|
+
|
18
|
+
|
19
|
+
class PurchasesResponseListener(PythonJavaClass):
|
20
|
+
__javainterfaces__ = ["com/android/billingclient/api/PurchasesResponseListener"]
|
21
|
+
__javacontext__ = "app"
|
22
|
+
|
23
|
+
def __init__(self, callback):
|
24
|
+
self.callback = callback
|
25
|
+
|
26
|
+
@java_method("(Lcom/android/billingclient/api/BillingResult;Ljava/util/List;)V")
|
27
|
+
def onQueryPurchasesResponse(self, billing_result, purchases):
|
28
|
+
self.callback(billing_result, purchases)
|
@@ -44,11 +44,12 @@ from android.activity import _activity as activity # noqa
|
|
44
44
|
from sjbillingclient.jclass.consume import ConsumeParams
|
45
45
|
from sjbillingclient.jclass.purchase import PendingPurchasesParams
|
46
46
|
from sjbillingclient.jclass.queryproduct import QueryProductDetailsParams, QueryProductDetailsParamsProduct
|
47
|
+
from sjbillingclient.jclass.querypurchases import QueryPurchasesParams
|
47
48
|
from sjbillingclient.jinterface.acknowledge import AcknowledgePurchaseResponseListener
|
48
49
|
from sjbillingclient.jinterface.billing import BillingClientStateListener
|
49
50
|
from sjbillingclient.jinterface.consume import ConsumeResponseListener
|
50
51
|
from sjbillingclient.jinterface.product import ProductDetailsResponseListener
|
51
|
-
from sjbillingclient.jinterface.purchases import PurchasesUpdatedListener
|
52
|
+
from sjbillingclient.jinterface.purchases import PurchasesUpdatedListener, PurchasesResponseListener
|
52
53
|
|
53
54
|
ERROR_NO_BASE_PLAN = "You don't have a base plan"
|
54
55
|
ERROR_NO_BASE_PLAN_ID = "You don't have a base plan id"
|
@@ -76,13 +77,16 @@ class BillingClient:
|
|
76
77
|
:type __consume_response_listener: ConsumeResponseListener | None
|
77
78
|
:ivar __acknowledge_purchase_response_listener: Listener handling responses for acknowledging purchases.
|
78
79
|
:type __acknowledge_purchase_response_listener: AcknowledgePurchaseResponseListener | None
|
80
|
+
:type __purchases_response_listener: PurchasesResponseListener | None handling responses for purchase queries.
|
79
81
|
"""
|
80
82
|
|
81
83
|
def __init__(
|
82
84
|
self,
|
83
85
|
on_purchases_updated,
|
86
|
+
enable_auto_service_reconnection: bool = True,
|
84
87
|
enable_one_time_products: bool = True,
|
85
|
-
enable_prepaid_plans: bool = False
|
88
|
+
enable_prepaid_plans: bool = False,
|
89
|
+
enable_external_offer: bool = False,
|
86
90
|
) -> None:
|
87
91
|
"""
|
88
92
|
Initializes an instance of the class with the given purchase update callback.
|
@@ -96,6 +100,7 @@ class BillingClient:
|
|
96
100
|
self.__product_details_response_listener = None
|
97
101
|
self.__consume_response_listener = None
|
98
102
|
self.__acknowledge_purchase_response_listener = None
|
103
|
+
self.__purchases_response_listener = None
|
99
104
|
|
100
105
|
self.__purchase_update_listener = PurchasesUpdatedListener(on_purchases_updated)
|
101
106
|
pending_purchase_params = PendingPurchasesParams.newBuilder()
|
@@ -103,14 +108,18 @@ class BillingClient:
|
|
103
108
|
pending_purchase_params.enableOneTimeProducts()
|
104
109
|
if enable_prepaid_plans:
|
105
110
|
pending_purchase_params.enablePrepaidPlans()
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
.
|
111
|
+
|
112
|
+
billing_client = SJBillingClient.newBuilder(activity.context)
|
113
|
+
if enable_external_offer:
|
114
|
+
billing_client.enableExternalOffer()
|
115
|
+
if enable_auto_service_reconnection:
|
116
|
+
billing_client.enableAutoServiceReconnection()
|
117
|
+
self.__billing_client = billing_client \
|
118
|
+
.setListener(self.__purchase_update_listener) \
|
119
|
+
.enablePendingPurchases(pending_purchase_params.build()) \
|
110
120
|
.build()
|
111
|
-
)
|
112
121
|
|
113
|
-
def start_connection(self, on_billing_setup_finished, on_billing_service_disconnected) -> None:
|
122
|
+
def start_connection(self, on_billing_setup_finished, on_billing_service_disconnected=lambda: None) -> None:
|
114
123
|
"""
|
115
124
|
Starts a connection with the billing client and initializes the billing
|
116
125
|
client state listener. This method sets up a listener to handle billing
|
@@ -140,6 +149,26 @@ class BillingClient:
|
|
140
149
|
"""
|
141
150
|
self.__billing_client.endConnection()
|
142
151
|
|
152
|
+
def query_purchase_async(self, product_type: str, on_query_purchases_response) -> None:
|
153
|
+
"""
|
154
|
+
Queries purchases asynchronously for a given product type.
|
155
|
+
|
156
|
+
This function utilizes the provided purchases response callback to handle the
|
157
|
+
resulting response from the query.
|
158
|
+
|
159
|
+
:param product_type: The type of the products to query purchases for (e.g., "inapp" or "subs").
|
160
|
+
:param on_query_purchases_response: A callback function that is triggered when the
|
161
|
+
purchases query is complete.
|
162
|
+
:return: None
|
163
|
+
"""
|
164
|
+
|
165
|
+
params = (QueryPurchasesParams.newBuilder()
|
166
|
+
.setProductType(product_type)
|
167
|
+
.build())
|
168
|
+
|
169
|
+
self.__purchases_response_listener = PurchasesResponseListener(on_query_purchases_response)
|
170
|
+
self.__billing_client.queryPurchasesAsync(params, self.__purchases_response_listener)
|
171
|
+
|
143
172
|
def query_product_details_async(self, product_type: str, products_ids: List[str],
|
144
173
|
on_product_details_response) -> None:
|
145
174
|
"""
|
@@ -188,6 +217,46 @@ class BillingClient:
|
|
188
217
|
.setProductType(product_type)
|
189
218
|
.build())
|
190
219
|
|
220
|
+
@staticmethod
|
221
|
+
def get_purchase(purchase) -> Dict:
|
222
|
+
"""
|
223
|
+
Retrieves detailed information from a purchase object.
|
224
|
+
|
225
|
+
This function extracts important details from a purchase object, such as
|
226
|
+
product IDs, purchase token, purchase state, and other relevant information.
|
227
|
+
The extracted details are then returned as a dictionary.
|
228
|
+
|
229
|
+
:param purchase: The purchase object to extract information from.
|
230
|
+
:type purchase: Purchase
|
231
|
+
:return: A dictionary containing detailed information about the purchase.
|
232
|
+
:rtype: Dict
|
233
|
+
"""
|
234
|
+
account_identifiers = purchase.getAccountIdentifiers()
|
235
|
+
pending_purchase_update = purchase.getPendingPurchaseUpdate()
|
236
|
+
|
237
|
+
return {
|
238
|
+
"products": list(purchase.getProducts()),
|
239
|
+
"purchase_token": purchase.getPurchaseToken(),
|
240
|
+
"purchase_state": purchase.getPurchaseState(),
|
241
|
+
"purchase_time": purchase.getPurchaseTime(),
|
242
|
+
"order_id": purchase.getOrderId(),
|
243
|
+
"quantity": purchase.getQuantity(),
|
244
|
+
"is_acknowledged": purchase.isAcknowledged(),
|
245
|
+
"is_auto_renewing": purchase.isAutoRenewing(),
|
246
|
+
"original_json": purchase.getOriginalJson(),
|
247
|
+
"signature": purchase.getSignature(),
|
248
|
+
"package_name": purchase.getPackageName(),
|
249
|
+
"developer_payload": purchase.getDeveloperPayload(),
|
250
|
+
"account_identifiers": {
|
251
|
+
"obfuscated_account_id": account_identifiers.getObfuscatedAccountId(),
|
252
|
+
"obfuscated_profile_id": account_identifiers.getObfuscatedProfileId(),
|
253
|
+
},
|
254
|
+
"pending_purchase_update": {
|
255
|
+
"products": list(pending_purchase_update.getProducts() or []),
|
256
|
+
"purchase_token": pending_purchase_update.getPurchaseToken(),
|
257
|
+
} if pending_purchase_update else None
|
258
|
+
}
|
259
|
+
|
191
260
|
@staticmethod
|
192
261
|
def get_unfetched_product(unfetched_product) -> Dict:
|
193
262
|
"""
|
@@ -325,7 +394,6 @@ class BillingClient:
|
|
325
394
|
self._create_product_params(product_detail, offer_token)
|
326
395
|
for product_detail in product_details
|
327
396
|
]
|
328
|
-
print(product_params_list)
|
329
397
|
|
330
398
|
billing_flow_params = (BillingFlowParams.newBuilder()
|
331
399
|
.setProductDetailsParamsList(JavaList.of(*product_params_list))
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: sjbillingclient
|
3
|
-
Version: 0.
|
3
|
+
Version: 1.0.0
|
4
4
|
Summary: A Python wrapper for the Google Play Billing Library that facilitates in-app purchases and subscriptions in Android applications
|
5
5
|
Home-page: https://github.com/SimpleJnius/sj-android-billingclient
|
6
6
|
Author: Kenechukwu Akubue
|
@@ -21,10 +21,6 @@ Description-Content-Type: text/markdown
|
|
21
21
|
|
22
22
|
# SJBillingClient (Google Play Billing SDK for Python)
|
23
23
|
|
24
|
-
<!-- GitAds-Verify: 71CCWMQSMVD67LS4WF4N44EXISSL2UTQ -->
|
25
|
-
## GitAds Sponsored
|
26
|
-
[](https://gitads.dev/v1/ad-track?source=simplejnius/sj-android-billingclient@github)
|
27
|
-
|
28
24
|
## Overview
|
29
25
|
|
30
26
|
SJBillingClient is a Python wrapper for the Google Play Billing Library that facilitates in-app purchases and subscriptions in Android applications. It provides a high-level, Pythonic interface to interact with Google Play's billing system, making it easier to implement and manage in-app purchases in Python-based Android apps (like those built with Kivy/Python-for-Android).
|
@@ -41,14 +37,18 @@ SJBillingClient is a Python wrapper for the Google Play Billing Library that fac
|
|
41
37
|
|
42
38
|
- Python 3.9+
|
43
39
|
- pyjnius 1.6.1+
|
44
|
-
- Android application with Google Play Billing Library (version 8.0.0
|
40
|
+
- Android application with Google Play Billing Library (version 8.0.0 required)
|
41
|
+
|
42
|
+
> **Note**: This library is specifically designed for Google Play Billing Library version 8.0.0. Earlier or later versions may not be compatible due to API changes.
|
45
43
|
|
46
44
|
## Installation
|
47
45
|
|
48
46
|
```shell
|
49
47
|
# Using pip
|
50
48
|
pip install sjbillingclient
|
49
|
+
````
|
51
50
|
|
51
|
+
```rpmspec
|
52
52
|
# In Buildozer (add to buildozer.spec)
|
53
53
|
requirements = sjbillingclient
|
54
54
|
android.gradle_dependencies = com.android.billingclient:billing:8.0.0
|
@@ -161,6 +161,37 @@ def on_acknowledge_purchase_response(billing_result):
|
|
161
161
|
client.acknowledge_purchase(purchase.getPurchaseToken(), on_acknowledge_purchase_response)
|
162
162
|
```
|
163
163
|
|
164
|
+
### Querying Purchases
|
165
|
+
|
166
|
+
```python
|
167
|
+
from sjbillingclient.tools import BillingClient
|
168
|
+
from sjbillingclient.jclass.billing import ProductType, BillingResponseCode
|
169
|
+
from sjbillingclient.jclass.purchase import PurchaseState
|
170
|
+
|
171
|
+
def on_query_purchases_response(billing_result, purchases):
|
172
|
+
if billing_result.getResponseCode() == BillingResponseCode.OK:
|
173
|
+
if purchases and not purchases.isEmpty():
|
174
|
+
for i in range(purchases.size()):
|
175
|
+
purchase = purchases.get(i)
|
176
|
+
# Get formatted purchase details
|
177
|
+
purchase_details = client.get_purchase(purchase)
|
178
|
+
print(f"Products: {purchase_details['products']}")
|
179
|
+
print(f"Purchase token: {purchase_details['purchase_token']}")
|
180
|
+
print(f"Purchase state: {purchase_details['purchase_state']}")
|
181
|
+
|
182
|
+
# Handle the purchase based on its state
|
183
|
+
if purchase_details['purchase_state'] == PurchaseState.PURCHASED:
|
184
|
+
if not purchase_details['is_acknowledged']:
|
185
|
+
# Acknowledge the purchase
|
186
|
+
client.acknowledge_purchase(purchase.getPurchaseToken(), on_acknowledge_purchase_response)
|
187
|
+
|
188
|
+
# Query purchases for a specific product type
|
189
|
+
client.query_purchase_async(
|
190
|
+
product_type=ProductType.INAPP,
|
191
|
+
on_query_purchases_response=on_query_purchases_response
|
192
|
+
)
|
193
|
+
```
|
194
|
+
|
164
195
|
### Kivy Integration Example
|
165
196
|
|
166
197
|
Here's a complete example of integrating SJBillingClient with a Kivy application:
|
@@ -284,7 +315,7 @@ class HomeScreen(Screen):
|
|
284
315
|
product_id = self.ids.btn.product_id
|
285
316
|
if billing_result.getResponseCode() == BillingResponseCode.OK:
|
286
317
|
self.billing_client.query_product_details_async(
|
287
|
-
product_type=ProductType.SUBS if self.ids.subscribe else ProductType.INAPP,
|
318
|
+
product_type=ProductType.SUBS if self.ids.subscribe.active else ProductType.INAPP,
|
288
319
|
products_ids=[product_id],
|
289
320
|
on_product_details_response=self.on_product_details_response,
|
290
321
|
)
|
@@ -428,6 +459,16 @@ The main class for interacting with Google Play Billing.
|
|
428
459
|
- `unfetched_product`: Unfetched product object
|
429
460
|
- Returns a dictionary with product ID, type, and status code
|
430
461
|
|
462
|
+
- `query_purchase_async(product_type, on_query_purchases_response)`:
|
463
|
+
- Queries purchases asynchronously
|
464
|
+
- `product_type`: Type of products (INAPP or SUBS)
|
465
|
+
- `on_query_purchases_response`: Callback for purchases response
|
466
|
+
|
467
|
+
- `get_purchase(purchase)`:
|
468
|
+
- Gets formatted purchase details
|
469
|
+
- `purchase`: Purchase object
|
470
|
+
- Returns a dictionary with purchase details including products, purchase token, purchase state, etc.
|
471
|
+
|
431
472
|
#### Purchase Methods
|
432
473
|
|
433
474
|
- `launch_billing_flow(product_details, offer_token=None)`:
|
@@ -475,6 +516,41 @@ Result of a product details query.
|
|
475
516
|
- `getProductDetailsList()`: Gets the list of product details
|
476
517
|
- `getUnfetchedProductList()`: Gets the list of unfetched products
|
477
518
|
|
519
|
+
### Purchase
|
520
|
+
|
521
|
+
Represents a purchase made by a user.
|
522
|
+
|
523
|
+
#### Methods
|
524
|
+
|
525
|
+
- `getProducts()`: Gets the list of product IDs associated with the purchase
|
526
|
+
- `getPurchaseToken()`: Gets the token that uniquely identifies the purchase
|
527
|
+
|
528
|
+
### PurchaseState
|
529
|
+
|
530
|
+
Constants for purchase states:
|
531
|
+
|
532
|
+
- `PurchaseState.PENDING`: Purchase is pending
|
533
|
+
- `PurchaseState.PURCHASED`: Purchase is completed
|
534
|
+
- `PurchaseState.UNSPECIFIED`: Purchase state is unspecified
|
535
|
+
|
536
|
+
### PendingPurchaseUpdate
|
537
|
+
|
538
|
+
Represents a pending update to a purchase.
|
539
|
+
|
540
|
+
#### Methods
|
541
|
+
|
542
|
+
- `getProducts()`: Gets the list of product IDs associated with the pending purchase update
|
543
|
+
- `getPurchaseToken()`: Gets the token that uniquely identifies the pending purchase update
|
544
|
+
|
545
|
+
### AccountIdentifiers
|
546
|
+
|
547
|
+
Contains account identifiers for a purchase.
|
548
|
+
|
549
|
+
#### Methods
|
550
|
+
|
551
|
+
- `getObfuscatedAccountId()`: Gets the obfuscated account ID
|
552
|
+
- `getProfileId()`: Gets the profile ID
|
553
|
+
|
478
554
|
### ProductType
|
479
555
|
|
480
556
|
Constants for product types:
|
@@ -482,6 +558,48 @@ Constants for product types:
|
|
482
558
|
- `ProductType.INAPP`: One-time purchases
|
483
559
|
- `ProductType.SUBS`: Subscriptions
|
484
560
|
|
561
|
+
### BillingFlowParamsBuilder
|
562
|
+
|
563
|
+
Builder for BillingFlowParams.
|
564
|
+
|
565
|
+
#### Methods
|
566
|
+
|
567
|
+
- `build()`: Builds the BillingFlowParams object
|
568
|
+
- `setIsOfferPersonalized(boolean)`: Sets whether the offer is personalized
|
569
|
+
- `setObfuscatedAccountId(String)`: Sets the obfuscated account ID
|
570
|
+
- `setObfuscatedProfileId(String)`: Sets the obfuscated profile ID
|
571
|
+
- `setProductDetailsParamsList(List)`: Sets the list of product details parameters
|
572
|
+
- `setSubscriptionUpdateParams(SubscriptionUpdateParams)`: Sets the subscription update parameters
|
573
|
+
|
574
|
+
### SubscriptionUpdateParams
|
575
|
+
|
576
|
+
Parameters for updating a subscription.
|
577
|
+
|
578
|
+
#### Methods
|
579
|
+
|
580
|
+
- `newBuilder()`: Creates a new builder for SubscriptionUpdateParams
|
581
|
+
- `build()`: Builds the SubscriptionUpdateParams object
|
582
|
+
|
583
|
+
### SubscriptionUpdateParamsBuilder
|
584
|
+
|
585
|
+
Builder for SubscriptionUpdateParams.
|
586
|
+
|
587
|
+
#### Methods
|
588
|
+
|
589
|
+
- `build()`: Builds the SubscriptionUpdateParams object
|
590
|
+
- `setOldPurchaseToken(String)`: Sets the token of the old purchase to be replaced
|
591
|
+
- `setSubscriptionReplacementMode(int)`: Sets the replacement mode for the subscription
|
592
|
+
|
593
|
+
### ReplacementMode
|
594
|
+
|
595
|
+
Constants for subscription replacement modes:
|
596
|
+
|
597
|
+
- `ReplacementMode.CHARGE_FULL_PRICE`: Charge the full price for the new subscription
|
598
|
+
- `ReplacementMode.CHARGE_PRORATED_PRICE`: Charge a prorated price for the new subscription
|
599
|
+
- `ReplacementMode.DEFERRED`: Defer the replacement until the next billing cycle
|
600
|
+
- `ReplacementMode.WITHOUT_PRORATION`: Replace without proration
|
601
|
+
- `ReplacementMode.WITH_TIME_PRORATION`: Replace with time proration
|
602
|
+
|
485
603
|
### BillingResponseCode
|
486
604
|
|
487
605
|
Constants for billing response codes:
|
@@ -0,0 +1,19 @@
|
|
1
|
+
sjbillingclient/__init__.py,sha256=i__3SUZ1MIcciCmCJM43fMtwFaglkoBT0acnbanUulo,125
|
2
|
+
sjbillingclient/jclass/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
3
|
+
sjbillingclient/jclass/accountidentifiers.py,sha256=7LzLeRPIBCkzyyeBMMxTOqEiTp1dKHpjQ-fzHMH9PH4,354
|
4
|
+
sjbillingclient/jclass/acknowledge.py,sha256=dsS25l7SgvB-avfPRjRyRsb9SxiZsFAm4TP1V-CsGs4,357
|
5
|
+
sjbillingclient/jclass/billing.py,sha256=eNQLcOc-duy7vfPikAy_bAuA7i64Kel27HWPUyiCuHQ,8486
|
6
|
+
sjbillingclient/jclass/consume.py,sha256=a924B3OOfg5jAlOWvFG1lfYvRsZd-XX2G2STBlsJRGM,309
|
7
|
+
sjbillingclient/jclass/purchase.py,sha256=BmkUhWHhoyHf70j0xHDjaIEZ4Mjg3iZcxlEjfVYr5ps,2439
|
8
|
+
sjbillingclient/jclass/queryproduct.py,sha256=wbrURx5kiWPzhd2DIDb9QUJUZE9RzX57VZTOI487ksY,2157
|
9
|
+
sjbillingclient/jclass/querypurchases.py,sha256=njhAhGmjJKPOTsaCPMEWc2ZD_wBubjDzsI0fjZDuKO8,730
|
10
|
+
sjbillingclient/jinterface/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
11
|
+
sjbillingclient/jinterface/acknowledge.py,sha256=OG5GWYO1TXfC7nscn8pPjsrdm2BGOCASRCzscKfyPFM,522
|
12
|
+
sjbillingclient/jinterface/billing.py,sha256=lwBGN8Xe0Qbc1DCRSShrhL8oGqRbjugwrgNspEK-nmc,1265
|
13
|
+
sjbillingclient/jinterface/consume.py,sha256=DiugwpRreoVLpPjeHSkNMgncg5f3HnIBCUh0OIyrWhI,524
|
14
|
+
sjbillingclient/jinterface/product.py,sha256=kr_oPhRnQd0xbZItFLtACjBhZsnUV8q-kooqG_biVPs,627
|
15
|
+
sjbillingclient/jinterface/purchases.py,sha256=LNi4tJIU7TSpiIhmWZDITdyrBe8pNlPnXSQUQntQSWw,1036
|
16
|
+
sjbillingclient/tools/__init__.py,sha256=UKL-d-a_DQk9sS_EidCVXHrZhUBT23PqZjguInhK6LA,24508
|
17
|
+
sjbillingclient-1.0.0.dist-info/METADATA,sha256=Aj8ib_L_NpAFlhPEALXzdEr2mnUiDpTcCXOfdcPVHDg,23143
|
18
|
+
sjbillingclient-1.0.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
19
|
+
sjbillingclient-1.0.0.dist-info/RECORD,,
|
@@ -1,17 +0,0 @@
|
|
1
|
-
sjbillingclient/__init__.py,sha256=i__3SUZ1MIcciCmCJM43fMtwFaglkoBT0acnbanUulo,125
|
2
|
-
sjbillingclient/jclass/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
3
|
-
sjbillingclient/jclass/acknowledge.py,sha256=FeaiOsIR2_WxJQC56gaeCtOPTEWb7Dz7AuWE6VYVMJI,358
|
4
|
-
sjbillingclient/jclass/billing.py,sha256=Hkk_yvnPQel0Fw_SFVdhP3unmhRkWNDVUa4RM1qhzdY,5499
|
5
|
-
sjbillingclient/jclass/consume.py,sha256=Hh8sLGosVvs22NhdQRudFc_NP_ahvrJSJdJTM-_nLBQ,310
|
6
|
-
sjbillingclient/jclass/purchase.py,sha256=trFRSDHdMUPZsAxdyU7HuChT0qicDO-EjfPp9d6unrA,844
|
7
|
-
sjbillingclient/jclass/queryproduct.py,sha256=Akuxy3fO1djerVPidqmjUclKVtIDmlaNJxZDbyUWOUw,1115
|
8
|
-
sjbillingclient/jinterface/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
9
|
-
sjbillingclient/jinterface/acknowledge.py,sha256=OG5GWYO1TXfC7nscn8pPjsrdm2BGOCASRCzscKfyPFM,522
|
10
|
-
sjbillingclient/jinterface/billing.py,sha256=lwBGN8Xe0Qbc1DCRSShrhL8oGqRbjugwrgNspEK-nmc,1265
|
11
|
-
sjbillingclient/jinterface/consume.py,sha256=DiugwpRreoVLpPjeHSkNMgncg5f3HnIBCUh0OIyrWhI,524
|
12
|
-
sjbillingclient/jinterface/product.py,sha256=kr_oPhRnQd0xbZItFLtACjBhZsnUV8q-kooqG_biVPs,627
|
13
|
-
sjbillingclient/jinterface/purchases.py,sha256=BG6xF3H-35_XhiRr2kWDb1jzsxJ-hIw-jaEi-uSkTmY,574
|
14
|
-
sjbillingclient/tools/__init__.py,sha256=PqsUr6tIBdAUN4NNKvWR3aRdNQ-ZN84MAzkBKcm6sik,21127
|
15
|
-
sjbillingclient-0.2.2.dist-info/METADATA,sha256=54l9LJqO52QEOq58878VLNLOJIgFfkEw_dTpa7wqmuo,19028
|
16
|
-
sjbillingclient-0.2.2.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
17
|
-
sjbillingclient-0.2.2.dist-info/RECORD,,
|
File without changes
|