Last active
October 11, 2024 14:45
-
-
Save mikegogulski/83ce5f6ac0633ca6cac913d0dab4b9eb to your computer and use it in GitHub Desktop.
Copy Stripe production products and prices to test environment
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
### The best way to start is to use the "Delete all test data" button at https://dashboard.stripe.com/test/developers | |
### Setup: | |
import stripe | |
test = 'sk_test_51IXXXyoursecretkey' | |
prod = 'sk_live_51IXXXyoursecretkey' | |
skip_fields = ['amount_decimal', 'unit_amount_decimal', 'type', 'object', 'created', 'livemode', 'updated',] | |
ignore_products = ['prod_JNXXXyourproductID',] | |
### Fetch production products and prices | |
stripe.api_key = prod | |
prodproducts = ('Product', stripe.Product.list(active=True)) | |
prodprices = ('Price', stripe.Price.list(active=True)) | |
stripe.api_key = test | |
### Define some functions | |
def clear_stripe_things(thing: tuple) -> None: | |
''' | |
Clear out test products/prices | |
''' | |
print('Clearing', thing[0]) | |
for p in getattr(stripe, thing[0]).list(): | |
print('Clearing', p.get('id'), '-', p.get('name')) | |
if p.get('product') in ignore_products: | |
print('Ignoring') | |
continue | |
if not p.get('active'): | |
print('Inactive, skipping') | |
continue | |
if p.get('livemode'): | |
print('LIVE MODE THING! Skipping') | |
continue | |
try: | |
getattr(stripe, thing[0]).modify(p.get('id'), active=False) | |
except Exception as e: | |
print('Exception modifying for', p) | |
print(e) | |
pass | |
try: | |
p.delete() | |
except Exception as e: | |
print('Exception deleting for', p.get('id')) | |
print(e) | |
continue | |
def upload_products() -> None: | |
''' | |
Copy production products to test, preserving IDs | |
''' | |
print('Uploading products') | |
up = list() | |
for p in prodproducts[1].get('data'): | |
print('Queueing', p.get('id'), '-', p.get('name')) | |
if p.get('product') in ignore_products: | |
print('Ignoring') | |
continue | |
up.append({k:v for k,v in p.items() if k not in skip_fields}) | |
for p in up: | |
try: | |
print('Uploading', p.get('id'), '-', p.get('name')) | |
print(up) | |
stripe.Product.create(**p) | |
except Exception as e: | |
print('EXCEPTION creating', p) | |
print('EXCEPTION:', e) | |
continue | |
def get_by_kv(lis, k, v): | |
''' | |
Return first element in list where key, value matches k, v in dictionary | |
''' | |
for e in lis: | |
if e.get(k) == v: | |
return e | |
def upload_prices() -> None: | |
''' | |
Upload prices to Stripe, preserving product ID correspondences | |
''' | |
skips = skip_fields + ['id'] | |
for p in prodproducts[1]: | |
print('Uploading for', p.get('id'), '-', p.get('name')) | |
if not p.get('active'): | |
print('Inactive product, skipping') | |
continue | |
# x = get_by_kv(prodprices[1], 'product', p.get('id')) | |
# print(x) | |
prod_price = get_by_kv(prodprices[1], 'product', p.get('id')) | |
print('prod_price', prod_price) | |
test_price = {k:v for k,v in prod_price.items() if k not in skips} | |
print('test_price', test_price) | |
try: | |
stripe.Price.create(**test_price) | |
except Exception as e: | |
print('EXCEPTION creating price', p) | |
print('EXCEPTION:', e) | |
continue | |
stripe.api_key = test | |
clear_stripe_things(prodprices) | |
clear_stripe_things(prodproducts) | |
stripe.api_key=test | |
upload_products() | |
upload_prices() |
@tomekit No doubt it is possible, but I'm not working with Stripe anymore so that feature won't be added here any time soon (or ever).
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
It seems to copy only monthly/default price. Is it possible to copy all prices associated with the product?