sjbillingclient 0.1.4__py3-none-any.whl → 0.2.1__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.
@@ -1,8 +1,16 @@
1
- from jnius import JavaClass, MetaJavaClass, JavaStaticMethod
1
+ from jnius import JavaClass, MetaJavaClass, JavaStaticMethod, JavaMethod
2
2
 
3
- __all__ = ("PendingPurchasesParams",)
3
+ __all__ = ("PendingPurchasesParams", "PendingPurchasesParamsBuilder")
4
4
 
5
5
 
6
6
  class PendingPurchasesParams(JavaClass, metaclass=MetaJavaClass):
7
7
  __javaclass__ = f"com/android/billingclient/api/PendingPurchasesParams"
8
8
  newBuilder = JavaStaticMethod("()Lcom/android/billingclient/api/PendingPurchasesParams$Builder;")
9
+
10
+
11
+ class PendingPurchasesParamsBuilder(JavaClass, metaclass=MetaJavaClass):
12
+ __javaclass__ = f"com/android/billingclient/api/PendingPurchasesParams$Builder"
13
+
14
+ build = JavaMethod("()Lcom/android/billingclient/api/PendingPurchasesParams;")
15
+ enableOneTimeProducts = JavaMethod("()Lcom/android/billingclient/api/PendingPurchasesParams$Builder;")
16
+ enablePrepaidPlans = JavaMethod("()Lcom/android/billingclient/api/PendingPurchasesParams$Builder;")
@@ -1,4 +1,4 @@
1
- from jnius import JavaClass, MetaJavaClass, JavaStaticMethod
1
+ from jnius import JavaClass, MetaJavaClass, JavaStaticMethod, JavaMethod
2
2
 
3
3
  __all__ = ("QueryProductDetailsParams", "QueryProductDetailsParamsProduct")
4
4
 
@@ -11,3 +11,11 @@ class QueryProductDetailsParams(JavaClass, metaclass=MetaJavaClass):
11
11
  class QueryProductDetailsParamsProduct(JavaClass, metaclass=MetaJavaClass):
12
12
  __javaclass__ = f"com/android/billingclient/api/QueryProductDetailsParams$Product"
13
13
  newBuilder = JavaStaticMethod("()Lcom/android/billingclient/api/QueryProductDetailsParams$Product$Builder;")
14
+
15
+
16
+ class QueryProductDetailsResult(JavaClass, metaclass=MetaJavaClass):
17
+ __javaclass__ = f"com/android/billingclient/api/QueryProductDetailsResult"
18
+ create = JavaStaticMethod("(Ljava/util/List;Ljava/util/List;)"
19
+ "Lcom/android/billingclient/api/QueryProductDetailsResult;")
20
+ getProductDetailsList = JavaMethod("()Ljava/util/List;")
21
+ getUnfetchedProductList = JavaMethod("()Ljava/util/List;")
@@ -10,6 +10,7 @@ class ProductDetailsResponseListener(PythonJavaClass):
10
10
  def __init__(self, callback):
11
11
  self.callback = callback
12
12
 
13
- @java_method("(Lcom/android/billingclient/api/BillingResult;Ljava/util/List;)V")
14
- def onProductDetailsResponse(self, billing_result, product_details_list):
15
- self.callback(billing_result, product_details_list)
13
+ @java_method("(Lcom/android/billingclient/api/BillingResult;"
14
+ "Lcom/android/billingclient/api/QueryProductDetailsResult;)V")
15
+ def onProductDetailsResponse(self, billing_result, product_details_result):
16
+ self.callback(billing_result, product_details_result)
@@ -42,6 +42,7 @@ from sjbillingclient.jclass.billing import BillingClient as SJBillingClient, Pro
42
42
  BillingFlowParams
43
43
  from android.activity import _activity as activity # noqa
44
44
  from sjbillingclient.jclass.consume import ConsumeParams
45
+ from sjbillingclient.jclass.purchase import PendingPurchasesParams
45
46
  from sjbillingclient.jclass.queryproduct import QueryProductDetailsParams, QueryProductDetailsParamsProduct
46
47
  from sjbillingclient.jinterface.acknowledge import AcknowledgePurchaseResponseListener
47
48
  from sjbillingclient.jinterface.billing import BillingClientStateListener
@@ -49,7 +50,6 @@ from sjbillingclient.jinterface.consume import ConsumeResponseListener
49
50
  from sjbillingclient.jinterface.product import ProductDetailsResponseListener
50
51
  from sjbillingclient.jinterface.purchases import PurchasesUpdatedListener
51
52
 
52
-
53
53
  ERROR_NO_BASE_PLAN = "You don't have a base plan"
54
54
  ERROR_NO_BASE_PLAN_ID = "You don't have a base plan id"
55
55
  ERROR_INVALID_PRODUCT_TYPE = "product_type not supported. Must be one of `ProductType.SUBS`, `ProductType.INAPP`"
@@ -77,7 +77,13 @@ class BillingClient:
77
77
  :ivar __acknowledge_purchase_response_listener: Listener handling responses for acknowledging purchases.
78
78
  :type __acknowledge_purchase_response_listener: AcknowledgePurchaseResponseListener | None
79
79
  """
80
- def __init__(self, on_purchases_updated) -> None:
80
+
81
+ def __init__(
82
+ self,
83
+ on_purchases_updated,
84
+ enable_one_time_products: bool = True,
85
+ enable_prepaid_plans: bool = False
86
+ ) -> None:
81
87
  """
82
88
  Initializes an instance of the class with the given purchase update callback.
83
89
 
@@ -92,10 +98,15 @@ class BillingClient:
92
98
  self.__acknowledge_purchase_response_listener = None
93
99
 
94
100
  self.__purchase_update_listener = PurchasesUpdatedListener(on_purchases_updated)
101
+ pending_purchase_params = PendingPurchasesParams.newBuilder()
102
+ if enable_one_time_products:
103
+ pending_purchase_params.enableOneTimeProducts()
104
+ if enable_prepaid_plans:
105
+ pending_purchase_params.enablePrepaidPlans()
95
106
  self.__billing_client = (
96
107
  SJBillingClient.newBuilder(activity.context)
97
108
  .setListener(self.__purchase_update_listener)
98
- .enablePendingPurchases()
109
+ .enablePendingPurchases(pending_purchase_params.build())
99
110
  .build()
100
111
  )
101
112
 
@@ -177,6 +188,28 @@ class BillingClient:
177
188
  .setProductType(product_type)
178
189
  .build())
179
190
 
191
+ @staticmethod
192
+ def get_unfetched_product(unfetched_product) -> Dict:
193
+ """
194
+ Retrieves detailed product information for an unfetched product.
195
+
196
+ This function takes an object representing an unfetched product and extracts
197
+ important details such as the product ID, product type, and status code.
198
+ The extracted details are then returned as a dictionary.
199
+
200
+ :param unfetched_product: The product object that has not yet been fetched.
201
+ Must provide methods to retrieve product ID, type, and status code.
202
+ :type unfetched_product: Any
203
+ :return: A dictionary containing detailed information about the unfetched
204
+ product, including its ID, type, and status code.
205
+ :rtype: Dict
206
+ """
207
+ return {
208
+ "product_id": unfetched_product.getProductId(),
209
+ "product_type": unfetched_product.getProductType(),
210
+ "status_code": unfetched_product.getStatusCode(),
211
+ }
212
+
180
213
  def get_product_details(self, product_details, product_type: str) -> List[Dict]:
181
214
  """
182
215
  Retrieves the details of a product based on the provided product type. The function processes
@@ -292,6 +325,7 @@ class BillingClient:
292
325
  self._create_product_params(product_detail, offer_token)
293
326
  for product_detail in product_details
294
327
  ]
328
+ print(product_params_list)
295
329
 
296
330
  billing_flow_params = (BillingFlowParams.newBuilder()
297
331
  .setProductDetailsParamsList(JavaList.of(*product_params_list))
@@ -1,7 +1,8 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sjbillingclient
3
- Version: 0.1.4
4
- Summary:
3
+ Version: 0.2.1
4
+ Summary: A Python wrapper for the Google Play Billing Library that facilitates in-app purchases and subscriptions in Android applications
5
+ Home-page: https://github.com/SimpleJnius/sj-android-billingclient
5
6
  Author: Kenechukwu Akubue
6
7
  Author-email: kengoon19@gmail.com
7
8
  Requires-Python: >=3.9,<4.0
@@ -12,6 +13,11 @@ Classifier: Programming Language :: Python :: 3.11
12
13
  Classifier: Programming Language :: Python :: 3.12
13
14
  Requires-Dist: poetry-core (>=2.1.3,<3.0.0)
14
15
  Requires-Dist: pyjnius (>=1.6.1,<2.0.0)
16
+ Project-URL: Bug Tracker, https://github.com/SimpleJnius/sj-android-billingclient/issues
17
+ Project-URL: Documentation, https://github.com/SimpleJnius/sj-android-billingclient/blob/master/README.md
18
+ Project-URL: Pull Requests, https://github.com/SimpleJnius/sj-android-billingclient/pulls
19
+ Project-URL: Repository, https://github.com/SimpleJnius/sj-android-billingclient.git
20
+ Project-URL: Source, https://github.com/SimpleJnius/sj-android-billingclient
15
21
  Description-Content-Type: text/markdown
16
22
 
17
23
  # SJBillingClient (Google Play Billing SDK for Python)
@@ -36,7 +42,7 @@ SJBillingClient is a Python wrapper for the Google Play Billing Library that fac
36
42
 
37
43
  - Python 3.9+
38
44
  - pyjnius 1.6.1+
39
- - Android application with Google Play Billing Library (version 7.1.1 recommended)
45
+ - Android application with Google Play Billing Library (version 8.0.0 recommended)
40
46
 
41
47
  ## Installation
42
48
 
@@ -46,7 +52,7 @@ pip install sjbillingclient
46
52
 
47
53
  # In Buildozer (add to buildozer.spec)
48
54
  requirements = sjbillingclient
49
- android.gradle_dependencies = com.android.billingclient:billing:7.1.1
55
+ android.gradle_dependencies = com.android.billingclient:billing:8.0.0
50
56
  ```
51
57
 
52
58
  ## Quick Start
@@ -170,14 +176,28 @@ from kivy.uix.screenmanager import ScreenManager, Screen
170
176
  from sjbillingclient.jclass.billing import BillingResponseCode, ProductType
171
177
  from sjbillingclient.tools import BillingClient
172
178
 
173
- # Load the KV file
174
179
  Builder.load_file(join(dirname(__file__), basename(__file__).split(".")[0] + ".kv"))
175
180
 
176
181
 
177
182
  class HomeScreen(Screen):
183
+ """
184
+ A screen that demonstrates Google Play Billing integration with Kivy.
185
+
186
+ This screen provides functionality to make in-app purchases and subscriptions
187
+ using the Google Play Billing Library through the SJBillingClient wrapper.
188
+
189
+ Attributes:
190
+ billing_client (BillingClient): The client used to interact with Google Play Billing.
191
+ """
178
192
  billing_client = None
179
193
 
180
- def purchase_or_subscribe(self):
194
+ def support(self):
195
+ """
196
+ Initializes the billing client and starts a connection to the Google Play Billing service.
197
+
198
+ This method is called when the user wants to make a purchase or subscription.
199
+ If a billing client already exists, it ends the connection before creating a new one.
200
+ """
181
201
  if self.billing_client:
182
202
  self.billing_client.end_connection()
183
203
 
@@ -188,6 +208,17 @@ class HomeScreen(Screen):
188
208
  )
189
209
 
190
210
  def on_purchases_updated(self, billing_result, null, purchases):
211
+ """
212
+ Callback method that is called when purchases are updated.
213
+
214
+ This method handles the result of a purchase flow, either acknowledging
215
+ a subscription or consuming a one-time purchase.
216
+
217
+ Args:
218
+ billing_result: The result of the billing operation.
219
+ null: Boolean indicating if the purchases list is null.
220
+ purchases: List of purchases that were updated.
221
+ """
191
222
  if billing_result.getResponseCode() == BillingResponseCode.OK and not null:
192
223
  for purchase in purchases:
193
224
  if self.ids.subscribe.active:
@@ -197,40 +228,96 @@ class HomeScreen(Screen):
197
228
  )
198
229
  else:
199
230
  self.billing_client.consume_async(purchase, self.on_consume_response)
231
+ print(billing_result.getResponseCode(), billing_result.getDebugMessage())
200
232
 
201
233
  def on_acknowledge_purchase_response(self, billing_result):
234
+ """
235
+ Callback method that is called when a purchase acknowledgement is complete.
236
+
237
+ Args:
238
+ billing_result: The result of the acknowledgement operation.
239
+ """
202
240
  print(billing_result.getDebugMessage())
203
241
  if billing_result.getResponseCode() == BillingResponseCode.OK:
204
242
  self.toast("Thank you for subscribing to buy us a cup of coffee! monthly")
205
243
 
206
244
  def on_consume_response(self, billing_result):
245
+ """
246
+ Callback method that is called when a purchase consumption is complete.
247
+
248
+ Args:
249
+ billing_result: The result of the consumption operation.
250
+ """
207
251
  if billing_result.getResponseCode() == BillingResponseCode.OK:
208
252
  self.toast("Thank you for buying us a cup of coffee!")
209
253
 
210
- def on_product_details_response(self, billing_result, product_details_list):
211
- for product_details in product_details_list:
212
- self.billing_client.get_product_details(
213
- product_details,
214
- ProductType.SUBS if self.ids.subscribe.active else ProductType.INAPP)
254
+ def on_product_details_response(self, billing_result, product_details_result):
255
+ """
256
+ Callback method that is called when product details are retrieved.
257
+
258
+ This method processes the product details and launches the billing flow.
259
+
260
+ Args:
261
+ billing_result: The result of the product details query.
262
+ product_details_result: The result containing product details and unfetched products.
263
+ """
264
+ product_details_list = product_details_result.getProductDetailsList()
265
+ unfetched_product_list = product_details_result.getUnfetchedProductList()
266
+
215
267
  if billing_result.getResponseCode() == BillingResponseCode.OK:
268
+ for product_details in product_details_list:
269
+ self.billing_client.get_product_details(
270
+ product_details,
271
+ ProductType.SUBS if self.ids.subscribe.active else ProductType.INAPP)
272
+ for unfetched_product in unfetched_product_list:
273
+ print(self.billing_client.get_unfetched_product(unfetched_product))
216
274
  self.billing_client.launch_billing_flow(product_details=product_details_list)
217
275
 
218
276
  def on_billing_setup_finished(self, billing_result):
277
+ """
278
+ Callback method that is called when the billing setup is complete.
279
+
280
+ This method queries product details if the billing setup was successful.
281
+
282
+ Args:
283
+ billing_result: The result of the billing setup operation.
284
+ """
219
285
  product_id = self.ids.btn.product_id
220
286
  if billing_result.getResponseCode() == BillingResponseCode.OK:
221
287
  self.billing_client.query_product_details_async(
222
- product_type=ProductType.SUBS if self.ids.subscribe.active else ProductType.INAPP,
288
+ product_type=ProductType.SUBS if self.ids.subscribe else ProductType.INAPP,
223
289
  products_ids=[product_id],
224
290
  on_product_details_response=self.on_product_details_response,
225
291
  )
226
292
 
227
293
  def toast(self, message):
294
+ """
295
+ Display a toast message.
296
+
297
+ This is a simple implementation that just prints the message.
298
+ In a real app, you would use platform-specific toast functionality.
299
+
300
+ Args:
301
+ message: The message to display.
302
+ """
228
303
  # Implementation of toast message (platform specific)
229
304
  print(message)
230
305
 
231
306
 
232
307
  class BillingApp(App):
308
+ """
309
+ Main application class for the SJBillingClient demo.
310
+
311
+ This class sets up the application and creates the screen manager
312
+ with the HomeScreen.
313
+ """
233
314
  def build(self):
315
+ """
316
+ Build the application UI.
317
+
318
+ Returns:
319
+ ScreenManager: The root widget of the application.
320
+ """
234
321
  # Create screen manager
235
322
  sm = ScreenManager()
236
323
  sm.add_widget(HomeScreen(name='home'))
@@ -276,7 +363,7 @@ if __name__ == '__main__':
276
363
  product_id: 'coffee_product_id'
277
364
  size_hint_y: None
278
365
  height: '60dp'
279
- on_release: root.purchase_or_subscribe()
366
+ on_release: root.support()
280
367
 
281
368
  Widget:
282
369
  # Spacer
@@ -284,13 +371,20 @@ if __name__ == '__main__':
284
371
 
285
372
  This example demonstrates:
286
373
 
287
- 1. A `HomeScreen` class that handles all billing operations
374
+ 1. A `HomeScreen` class that extends `Screen` and handles all billing operations
288
375
  2. A `BillingApp` class that sets up the Kivy application and screen manager
289
376
  3. A Kivy layout file that defines the UI with:
290
377
  - A checkbox to toggle between one-time purchase and subscription
291
378
  - A button to initiate the purchase flow
292
379
 
293
- The `purchase_or_subscribe` method is called when the button is pressed, which initializes the billing client and starts the connection. The various callback methods handle different stages of the billing process, including acknowledging purchases and consuming one-time purchases.
380
+ The `support` method is called when the button is pressed, which initializes the billing client and starts the connection. The various callback methods handle different stages of the billing process, including:
381
+ - Handling purchase updates with `on_purchases_updated`
382
+ - Acknowledging subscription purchases with `acknowledge_purchase`
383
+ - Consuming one-time purchases with `consume_async`
384
+ - Processing product details with `on_product_details_response`, including handling unfetched products
385
+ - Querying product details with `query_product_details_async`
386
+
387
+ This example is designed to be copy-and-paste runnable, with no need for the user to add or remove anything to test it.
294
388
 
295
389
  ## API Reference
296
390
 
@@ -298,16 +392,89 @@ The `purchase_or_subscribe` method is called when the button is pressed, which i
298
392
 
299
393
  The main class for interacting with Google Play Billing.
300
394
 
395
+ #### Constructor
396
+
397
+ - `__init__(on_purchases_updated, enable_one_time_products=True, enable_prepaid_plans=False)`:
398
+ - Initializes a new BillingClient instance
399
+ - `on_purchases_updated`: Callback function that will be triggered when purchases are updated
400
+ - `enable_one_time_products`: Boolean to enable one-time products (default: True)
401
+ - `enable_prepaid_plans`: Boolean to enable prepaid plans (default: False)
402
+
403
+ #### Connection Methods
404
+
405
+ - `start_connection(on_billing_setup_finished, on_billing_service_disconnected)`:
406
+ - Starts a connection with the billing client
407
+ - `on_billing_setup_finished`: Callback when billing setup is complete
408
+ - `on_billing_service_disconnected`: Callback when billing service is disconnected
409
+
410
+ - `end_connection()`:
411
+ - Ends the connection with the billing client
412
+
413
+ #### Product Details Methods
414
+
415
+ - `query_product_details_async(product_type, products_ids, on_product_details_response)`:
416
+ - Queries product details asynchronously
417
+ - `product_type`: Type of products (INAPP or SUBS)
418
+ - `products_ids`: List of product IDs to query
419
+ - `on_product_details_response`: Callback for product details response
420
+
421
+ - `get_product_details(product_details, product_type)`:
422
+ - Gets formatted product details
423
+ - `product_details`: Product details object
424
+ - `product_type`: Type of product (INAPP or SUBS)
425
+ - Returns a list of dictionaries with product details
426
+
427
+ - `get_unfetched_product(unfetched_product)`:
428
+ - Gets details about an unfetched product
429
+ - `unfetched_product`: Unfetched product object
430
+ - Returns a dictionary with product ID, type, and status code
431
+
432
+ #### Purchase Methods
433
+
434
+ - `launch_billing_flow(product_details, offer_token=None)`:
435
+ - Launches the billing flow for purchase
436
+ - `product_details`: List of product details objects
437
+ - `offer_token`: Optional token for subscription offers
438
+
439
+ - `consume_async(purchase, on_consume_response)`:
440
+ - Consumes a purchase asynchronously
441
+ - `purchase`: Purchase object to consume
442
+ - `on_consume_response`: Callback for consume response
443
+
444
+ - `acknowledge_purchase(purchase_token, on_acknowledge_purchase_response)`:
445
+ - Acknowledges a purchase
446
+ - `purchase_token`: Token of the purchase to acknowledge
447
+ - `on_acknowledge_purchase_response`: Callback for acknowledge response
448
+
449
+ ### PendingPurchasesParams
450
+
451
+ Parameters for handling pending purchases.
452
+
453
+ #### Methods
454
+
455
+ - `newBuilder()`: Creates a new builder for PendingPurchasesParams
456
+ - `build()`: Builds the PendingPurchasesParams object
457
+ - `enableOneTimeProducts()`: Enables one-time products
458
+ - `enablePrepaidPlans()`: Enables prepaid plans
459
+
460
+ ### QueryProductDetailsParams
461
+
462
+ Parameters for querying product details.
463
+
464
+ #### Methods
465
+
466
+ - `newBuilder()`: Creates a new builder for QueryProductDetailsParams
467
+ - `setProductList(product_list)`: Sets the list of products to query
468
+ - `build()`: Builds the QueryProductDetailsParams object
469
+
470
+ ### QueryProductDetailsResult
471
+
472
+ Result of a product details query.
473
+
301
474
  #### Methods
302
475
 
303
- - `__init__(on_purchases_updated)`: Initialize with a callback for purchase updates
304
- - `start_connection(on_billing_setup_finished, on_billing_service_disconnected)`: Start billing connection
305
- - `end_connection()`: End billing connection
306
- - `query_product_details_async(product_type, products_ids, on_product_details_response)`: Query product details
307
- - `get_product_details(product_details, product_type)`: Get formatted product details
308
- - `launch_billing_flow(product_details, offer_token=None)`: Launch purchase flow
309
- - `consume_async(purchase, on_consume_response)`: Consume a purchase
310
- - `acknowledge_purchase(purchase_token, on_acknowledge_purchase_response)`: Acknowledge a purchase
476
+ - `getProductDetailsList()`: Gets the list of product details
477
+ - `getUnfetchedProductList()`: Gets the list of unfetched products
311
478
 
312
479
  ### ProductType
313
480
 
@@ -320,10 +487,17 @@ Constants for product types:
320
487
 
321
488
  Constants for billing response codes:
322
489
 
323
- - `BillingResponseCode.OK`: Success
324
- - `BillingResponseCode.USER_CANCELED`: User canceled
325
- - `BillingResponseCode.SERVICE_UNAVAILABLE`: Service unavailable
326
- - And many others
490
+ - `BillingResponseCode.OK`: Success (0)
491
+ - `BillingResponseCode.USER_CANCELED`: User canceled (1)
492
+ - `BillingResponseCode.SERVICE_UNAVAILABLE`: Service unavailable (2)
493
+ - `BillingResponseCode.BILLING_UNAVAILABLE`: Billing unavailable (3)
494
+ - `BillingResponseCode.ITEM_UNAVAILABLE`: Item unavailable (4)
495
+ - `BillingResponseCode.DEVELOPER_ERROR`: Developer error (5)
496
+ - `BillingResponseCode.ERROR`: General error (6)
497
+ - `BillingResponseCode.ITEM_ALREADY_OWNED`: Item already owned (7)
498
+ - `BillingResponseCode.ITEM_NOT_OWNED`: Item not owned (8)
499
+ - `BillingResponseCode.SERVICE_DISCONNECTED`: Service disconnected (10)
500
+ - `BillingResponseCode.FEATURE_NOT_SUPPORTED`: Feature not supported (12)
327
501
 
328
502
  ## Contributing
329
503
 
@@ -3,15 +3,15 @@ sjbillingclient/jclass/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3
3
3
  sjbillingclient/jclass/acknowledge.py,sha256=FeaiOsIR2_WxJQC56gaeCtOPTEWb7Dz7AuWE6VYVMJI,358
4
4
  sjbillingclient/jclass/billing.py,sha256=Hkk_yvnPQel0Fw_SFVdhP3unmhRkWNDVUa4RM1qhzdY,5499
5
5
  sjbillingclient/jclass/consume.py,sha256=Hh8sLGosVvs22NhdQRudFc_NP_ahvrJSJdJTM-_nLBQ,310
6
- sjbillingclient/jclass/purchase.py,sha256=sLEihOLiyvwDIWBhHSpmMj1swNr4RJizceQOKmBqHM4,346
7
- sjbillingclient/jclass/queryproduct.py,sha256=0JkaC9E1Juxl79t7gJCUfrQntWiLWjfScSEI-mss8Lg,671
6
+ sjbillingclient/jclass/purchase.py,sha256=trFRSDHdMUPZsAxdyU7HuChT0qicDO-EjfPp9d6unrA,844
7
+ sjbillingclient/jclass/queryproduct.py,sha256=Akuxy3fO1djerVPidqmjUclKVtIDmlaNJxZDbyUWOUw,1115
8
8
  sjbillingclient/jinterface/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
9
  sjbillingclient/jinterface/acknowledge.py,sha256=OG5GWYO1TXfC7nscn8pPjsrdm2BGOCASRCzscKfyPFM,522
10
10
  sjbillingclient/jinterface/billing.py,sha256=lwBGN8Xe0Qbc1DCRSShrhL8oGqRbjugwrgNspEK-nmc,1265
11
11
  sjbillingclient/jinterface/consume.py,sha256=DiugwpRreoVLpPjeHSkNMgncg5f3HnIBCUh0OIyrWhI,524
12
- sjbillingclient/jinterface/product.py,sha256=rtlc-4hxToCa3buwNp8QufMYkoiUZHp_YXKeE-QZZyk,562
12
+ sjbillingclient/jinterface/product.py,sha256=kr_oPhRnQd0xbZItFLtACjBhZsnUV8q-kooqG_biVPs,627
13
13
  sjbillingclient/jinterface/purchases.py,sha256=BG6xF3H-35_XhiRr2kWDb1jzsxJ-hIw-jaEi-uSkTmY,574
14
- sjbillingclient/tools/__init__.py,sha256=g0k73jc9mcbAe86gM8Q_r9fp5dxHJWIbeqzO9Ne3xA4,19622
15
- sjbillingclient-0.1.4.dist-info/METADATA,sha256=6q45Ork4P_V9HG7Gtjx--ksqH5pxQ6UPOe0rRRA8VbM,12093
16
- sjbillingclient-0.1.4.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
17
- sjbillingclient-0.1.4.dist-info/RECORD,,
14
+ sjbillingclient/tools/__init__.py,sha256=PqsUr6tIBdAUN4NNKvWR3aRdNQ-ZN84MAzkBKcm6sik,21127
15
+ sjbillingclient-0.2.1.dist-info/METADATA,sha256=37LwwLdpsUuMjGIdi2pkMjehpZe-wzUM-bZFetIjNQo,19072
16
+ sjbillingclient-0.2.1.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
17
+ sjbillingclient-0.2.1.dist-info/RECORD,,