def start_pay(transaction_uuid, notes, **kw): """ Work with Solitude to begin a Bango payment. This puts the transaction in a state where it's ready to be fulfilled by Bango. """ # Because this is called from views, we get a new transaction every # time. If you re-use this task, you'd want to add some checking about the # transaction state. pay = notes['pay_request'] try: seller_uuid = get_seller_uuid(notes['issuer_key'], pay['request'].get('productData', '')) # Ask the marketplace for a valid price point. prices = mkt_client.get_price(pay['request']['pricePoint']) # Set up the product for sale. bill_id, seller_product = client.configure_product_for_billing( transaction_uuid, seller_uuid, pay['request']['id'], pay['request']['name'], # app/product name absolutify(reverse('bango.success')), absolutify(reverse('bango.error')), prices['prices'] ) client.slumber.generic.transaction(transaction_uuid).patch({ 'notes': json.dumps(notes), 'uid_pay': bill_id, 'status': constants.STATUS_PENDING }) except Exception, exc: log.exception('while configuring for payment') etype, val, tb = sys.exc_info() raise exc, None, tb
def start_pay(transaction_uuid, notes, **kw): """ Work with Solitude to begin a Bango payment. This puts the transaction in a state where it's ready to be fulfilled by Bango. """ # Because this is called from views, we get a new transaction every # time. If you re-use this task, you'd want to add some checking about the # transaction state. pay = notes["pay_request"] try: seller_uuid = get_seller_uuid(notes["issuer_key"], pay["request"].get("productData", "")) # Ask the marketplace for a valid price point. prices = mkt_client.get_price(pay["request"]["pricePoint"]) # Set up the product for sale. bill_id, seller_product = client.configure_product_for_billing( transaction_uuid, seller_uuid, pay["request"]["id"], pay["request"]["name"], # app/product name absolutify(reverse("bango.success")), absolutify(reverse("bango.error")), prices["prices"], ) trans_pk = client.slumber.generic.transaction.get_object(uuid=transaction_uuid)["resource_pk"] client.slumber.generic.transaction(trans_pk).patch( {"notes": json.dumps(notes), "uid_pay": bill_id, "status": constants.STATUS_PENDING} ) except Exception, exc: log.exception("while configuring for payment") etype, val, tb = sys.exc_info() raise exc, None, tb
def create_transaction(self, generic_buyer, generic_seller, generic_product, provider_product, provider_seller_uuid, product_name, transaction_uuid, prices, user_uuid, application_size, source, icon_url, mcc=None, mnc=None): log.info('transaction {tr}: bango product: {pr}' .format(tr=transaction_uuid, pr=provider_product['resource_uri'])) redirect_url_onsuccess = absolutify(reverse('bango.success')) redirect_url_onerror = absolutify(reverse('bango.error')) # This API call also creates a generic # transaction automatically. res = self.api.billing.post({ 'pageTitle': product_name, 'prices': prices, 'transaction_uuid': transaction_uuid, 'seller_product_bango': provider_product['resource_uri'], 'redirect_url_onsuccess': redirect_url_onsuccess, 'redirect_url_onerror': redirect_url_onerror, 'icon_url': icon_url, 'user_uuid': user_uuid, 'application_size': application_size, 'source': source }) bill_id = res['billingConfigurationId'] log.info('transaction {tr}: billing config ID: {bill}; ' 'prices: {pr}' .format(tr=transaction_uuid, bill=bill_id, pr=prices)) return bill_id, self._formatted_payment_url(bill_id)
def start_pay(transaction_uuid, notes, user_uuid, **kw): """ Work with Solitude to begin a Bango payment. This puts the transaction in a state where it's ready to be fulfilled by Bango. """ try: # This task is fired from multiple locations. This checks first to # see if it already ran. trans = (client.slumber.generic.transaction .get_object(uuid=transaction_uuid)) if trans['status'] in (constants.STATUS_RECEIVED, constants.STATUS_PENDING): log.info('trans %s (status=%r) already configured: ' 'skipping configure payments step' % (transaction_uuid, trans['status'])) return except ObjectDoesNotExist: pass pay = notes['pay_request'] try: seller_uuid = get_seller_uuid(notes['issuer_key'], pay['request'].get('productData', '')) # Ask the marketplace for a valid price point. prices = mkt_client.get_price(pay['request']['pricePoint']) log.debug('pricePoint=%s prices=%s' % (pay['request']['pricePoint'], prices['prices'])) try: icon_url = (get_icon_url(pay['request']) if settings.USE_PRODUCT_ICONS else None) except: log.exception('Calling get_icon_url') icon_url = None log.info('icon URL for %s: %s' % (transaction_uuid, icon_url)) # Set up the product for sale. bill_id, seller_product = client.configure_product_for_billing( transaction_uuid, seller_uuid, pay['request']['id'], pay['request']['name'], # app/product name absolutify(reverse('bango.success')), absolutify(reverse('bango.error')), prices['prices'], icon_url, user_uuid ) trans_pk = client.slumber.generic.transaction.get_object( uuid=transaction_uuid)['resource_pk'] client.slumber.generic.transaction(trans_pk).patch({ 'notes': json.dumps(notes), 'uid_pay': bill_id, 'status': constants.STATUS_PENDING }) except Exception, exc: log.exception('while configuring for payment') etype, val, tb = sys.exc_info() raise exc, None, tb
def create_transaction(self, generic_buyer, generic_seller, generic_product, provider_product, provider_seller_uuid, product_name, transaction_uuid, prices, user_uuid, application_size, source, icon_url, mcc=None, mnc=None): # TODO: Maybe make these real values. See bug 941952. # In the case of Zippy, it does not detect any of these values # itself. All other providers will detect these values without # help from Webpay. carrier = 'USA_TMOBILE' region = '123' pay_method = 'OPERATOR' # Note: most providers will use the prices array. price = '0.99' currency = 'EUR' provider_trans = self.api.transactions.post({ 'product_id': provider_product['resource_pk'], 'region': region, 'carrier': carrier, 'price': price, 'currency': currency, 'pay_method': pay_method, 'callback_success_url': absolutify( reverse('pay.callback_success_url')), 'callback_error_url': absolutify( reverse('pay.callback_error_url')), 'ext_transaction_id': transaction_uuid, 'success_url': absolutify(reverse('provider.success', args=[self.name])), 'error_url': absolutify(reverse('provider.error', args=[self.name])), 'product_image_url': icon_url, }) # Note that the old Bango code used to do get-or-create # but I can't tell if we need that or not. Let's wait until it breaks. # See solitude/lib/transactions/models.py trans = self.slumber.generic.transaction.post({ 'uuid': transaction_uuid, 'status': solitude_const.STATUS_PENDING, 'provider': solitude_const.PROVIDERS[self.name], 'buyer': generic_buyer['resource_uri'], 'seller': generic_seller['resource_uri'], 'seller_product': generic_product['resource_uri'], 'source': source, 'region': region, 'carrier': carrier, 'type': solitude_const.TYPE_PAYMENT, 'amount': price, 'currency': currency, }) log.info('made solitude trans {trans}'.format(trans=trans)) token = provider_trans['token'] return token, self._formatted_payment_url(token)
def create_transaction(self, generic_seller, generic_product, provider_product, product_name, transaction_uuid, prices, user_uuid, application_size, source, icon_url, mcc=None, mnc=None): try: # Do a sanity check to make sure we're actually on a Boku network. self.network_data[(mcc, mnc)] except KeyError: raise self.TransactionError('Unknown Boku network: ' 'mcc={mcc}; mnc={mnc}' .format(mcc=mcc, mnc=mnc)) country = mobile_codes.mcc(mcc) # TODO: consider using get_price_country here? mcc_region = COUNTRIES[mcc] price = None for mktpl_price in prices: # Given a list of all prices + currencies for this price point, # send Boku the one that matches the user's network/region. if mktpl_price['region'] == mcc_region: price = mktpl_price['price'] break if not price: log.error('No Boku price for region {r}: mcc={mcc}; mnc={mnc} ' 'in prices {pr}'.format(mcc=mcc, mnc=mnc, r=mcc_region, pr=prices)) raise self.TransactionError( 'Could not find a price for region {r}: mcc={mcc}; mnc={mnc}' .format(mcc=mcc, mnc=mnc, r=mcc_region)) provider_trans = self.api.transactions.post({ 'forward_url': absolutify(reverse('provider.wait_to_finish', args=[self.name])), 'callback_url': absolutify(reverse('provider.notification', args=[self.name])), 'country': country.alpha2, # TODO: figure out error callbacks in bug 987843. #'error_url': absolutify(reverse('provider.error', # args=[self.name])), 'price': price, 'seller_uuid': generic_seller['uuid'], 'transaction_uuid': transaction_uuid, 'user_uuid': user_uuid, }) log.info('{pr}: made provider trans {trans}' .format(pr=self.name, trans=provider_trans)) trans = self.slumber.generic.transaction.post({ 'provider': solitude_const.PROVIDERS[self.name], 'seller_product': generic_product['resource_uri'], 'source': solitude_const.PROVIDERS[self.name], 'status': solitude_const.STATUS_PENDING, 'type': solitude_const.TYPE_PAYMENT, 'uuid': transaction_uuid, }) log.info('{pr}: made solitude trans {trans}' .format(pr=self.name, trans=trans)) return provider_trans['transaction_id'], provider_trans['buy_url']
def configure_product_for_billing(self, transaction_uuid, seller_uuid, product_id, product_name, prices, icon_url, user_uuid, application_size, source='unknown'): """ Get the billing configuration ID for a Bango transaction. """ # TODO: remove this. # Do not edit this code. Add new logic to the SolitudeAPI. redirect_url_onsuccess = absolutify(reverse('bango.success')) redirect_url_onerror = absolutify(reverse('bango.error')) try: seller = self.slumber.generic.seller.get_object_or_404( uuid=seller_uuid) except ObjectDoesNotExist: raise SellerNotConfigured('Seller with uuid %s does not exist' % seller_uuid) seller_id = seller['resource_pk'] log.info('transaction %s: seller: %s' % (transaction_uuid, seller_id)) try: bango_product = self.slumber.bango.product.get_object_or_404( seller_product__seller=seller_id, seller_product__external_id=product_id) except ObjectDoesNotExist: bango_product = self.create_product(product_id, product_name, seller) log.info('transaction %s: bango product: %s' % (transaction_uuid, bango_product['resource_uri'])) res = self.slumber.bango.billing.post({ 'pageTitle': product_name, 'prices': prices, 'transaction_uuid': transaction_uuid, 'seller_product_bango': bango_product['resource_uri'], 'redirect_url_onsuccess': redirect_url_onsuccess, 'redirect_url_onerror': redirect_url_onerror, 'icon_url': icon_url, 'user_uuid': user_uuid, 'application_size': application_size, 'source': source }) bill_id = res['billingConfigurationId'] log.info('transaction %s: billing config ID: %s; ' 'prices: %s' % (transaction_uuid, bill_id, prices)) return bill_id, seller_id
def start_pay(transaction_uuid, notes, user_uuid, **kw): """ Work with Solitude to begin a Bango payment. This puts the transaction in a state where it's ready to be fulfilled by Bango. """ pay = notes['pay_request'] product_data = urlparse.parse_qs(pay['request'].get('productData', '')) try: seller_uuid = get_seller_uuid(notes['issuer_key'], product_data) try: application_size = int(product_data['application_size'][0]) except (KeyError, ValueError): application_size = None # Ask the marketplace for a valid price point. prices = mkt_client.get_price(pay['request']['pricePoint']) log.debug('pricePoint=%s prices=%s' % (pay['request']['pricePoint'], prices['prices'])) try: icon_url = (get_icon_url(pay['request']) if settings.USE_PRODUCT_ICONS else None) except: log.exception('Calling get_icon_url') icon_url = None log.info('icon URL for %s: %s' % (transaction_uuid, icon_url)) # Set up the product for sale. bill_id, seller_id = client.configure_product_for_billing( transaction_uuid, seller_uuid, pay['request']['id'], pay['request']['name'], # app/product name absolutify(reverse('bango.success')), absolutify(reverse('bango.error')), prices['prices'], icon_url, user_uuid, application_size, ) trans_pk = client.slumber.generic.transaction.get_object( uuid=transaction_uuid)['resource_pk'] client.slumber.generic.transaction(trans_pk).patch({ 'notes': json.dumps(notes), 'uid_pay': bill_id, 'status': constants.STATUS_PENDING }) except Exception, exc: log.exception('while configuring for payment') etype, val, tb = sys.exc_info() raise exc, None, tb
def create_transaction(self, generic_buyer, generic_seller, generic_product, provider_product, provider_seller_uuid, product_name, transaction_uuid, prices, user_uuid, application_size, source, icon_url, mcc=None, mnc=None): log.info('transaction {tr}: bango product: {pr}' .format(tr=transaction_uuid, pr=provider_product['resource_uri'])) redirect_url_onsuccess = absolutify(reverse('bango.success')) redirect_url_onerror = absolutify(reverse('bango.error')) try: res = self.api.billing.post({ 'pageTitle': product_name, 'prices': prices, 'transaction_uuid': transaction_uuid, 'seller_product_bango': provider_product['resource_uri'], 'redirect_url_onsuccess': redirect_url_onsuccess, 'redirect_url_onerror': redirect_url_onerror, 'icon_url': icon_url, 'user_uuid': user_uuid, 'application_size': application_size, 'source': source }) except HttpClientError: exc_type, exc_name, tb = sys.exc_info() raise ProviderTransactionError( 'Bango transaction create failed for transaction: {tr}' .format(tr=transaction_uuid)), None, tb bill_id = res['billingConfigurationId'] log.info('{pr}: made trans billing config ID: {bill}; ' 'transaction {tr}; prices: {prices}' .format(tr=transaction_uuid, bill=bill_id, prices=prices, pr=self.name)) trans = self.slumber.generic.transaction.post({ 'provider': solitude_const.PROVIDERS[self.name], 'buyer': generic_buyer['resource_uri'], 'seller': generic_seller['resource_uri'], 'seller_product': generic_product['resource_uri'], 'source': source, 'status': solitude_const.STATUS_PENDING, 'type': solitude_const.TYPE_PAYMENT, 'uuid': transaction_uuid, 'uid_pay': bill_id }) log.info('{pr}: made solitude trans {trans}' .format(pr=self.name, trans=trans)) return bill_id, self._formatted_payment_url(bill_id)
def start_pay(transaction_uuid, notes, user_uuid, **kw): """ Work with Solitude to begin a Bango payment. This puts the transaction in a state where it's ready to be fulfilled by Bango. """ key = notes['issuer_key'] pay = notes['pay_request'] product_data = urlparse.parse_qs(pay['request'].get('productData', '')) try: seller_uuid = get_seller_uuid(key, product_data) try: application_size = int(product_data['application_size'][0]) except (KeyError, ValueError): application_size = None # Ask the marketplace for a valid price point. prices = mkt_client.get_price(pay['request']['pricePoint']) log.debug('pricePoint=%s prices=%s' % (pay['request']['pricePoint'], prices['prices'])) try: icon_url = (get_icon_url(pay['request']) if settings.USE_PRODUCT_ICONS else None) except: log.exception('Calling get_icon_url') icon_url = None log.info('icon URL for %s: %s' % (transaction_uuid, icon_url)) # Set up the product for sale. bill_id, seller_id = client.configure_product_for_billing( transaction_uuid, seller_uuid, pay['request']['id'], pay['request']['name'], # app/product name absolutify(reverse('bango.success')), absolutify(reverse('bango.error')), prices['prices'], icon_url, user_uuid, application_size, source='marketplace' if is_marketplace(key) else 'other' ) trans_pk = client.slumber.generic.transaction.get_object( uuid=transaction_uuid)['resource_pk'] client.slumber.generic.transaction(trans_pk).patch({ 'notes': json.dumps(notes), 'uid_pay': bill_id, 'status': constants.STATUS_PENDING }) except Exception, exc: log.exception('while configuring for payment') etype, val, tb = sys.exc_info() raise exc, None, tb
def create_transaction(self, generic_seller, generic_product, provider_product, product_name, transaction_uuid, prices, user_uuid, application_size, source, icon_url, mcc=None, mnc=None): log.info('transaction {tr}: bango product: {pr}'.format( tr=transaction_uuid, pr=provider_product['resource_uri'])) redirect_url_onsuccess = absolutify(reverse('bango.success')) redirect_url_onerror = absolutify(reverse('bango.error')) # This API call also creates a generic # transaction automatically. res = self.api.billing.post({ 'pageTitle': product_name, 'prices': prices, 'transaction_uuid': transaction_uuid, 'seller_product_bango': provider_product['resource_uri'], 'redirect_url_onsuccess': redirect_url_onsuccess, 'redirect_url_onerror': redirect_url_onerror, 'icon_url': icon_url, 'user_uuid': user_uuid, 'application_size': application_size, 'source': source }) bill_id = res['billingConfigurationId'] log.info('transaction {tr}: billing config ID: {bill}; ' 'prices: {pr}'.format(tr=transaction_uuid, bill=bill_id, pr=prices)) return bill_id, self._formatted_payment_url(bill_id)
def start_pay(transaction_uuid, notes, **kw): """ Work with Solitude to begin a Bango payment. This puts the transaction in a state where it's ready to be fulfilled by Bango. """ # Because this is called from views, we get a new transaction every # time. If you re-use this task, you'd want to add some checking about the # transaction state. pay_request = notes['pay_request'] iss = Issuer.objects.get(pk=notes['issuer']) if notes['issuer'] else None try: seller_uuid = get_effective_issuer_key(iss, notes['issuer_key']) if seller_uuid == settings.KEY: # The issuer of the JWT is Firefox Marketplace. # This is a special case where we need to find the # actual Solitude/Bango seller_uuid to associate the # product to the right account. prod_data = pay_request['request'].get('productData', '') try: seller_uuid = urlparse.parse_qs(prod_data)['seller_uuid'][0] except KeyError: raise ValueError('Marketplace %r did not put a seller_uuid ' 'in productData: %r' % (settings.KEY, prod_data)) log.info('Using real seller_uuid %r for Marketplace %r ' 'app payment' % (seller_uuid, settings.KEY)) # Ask the marketplace for a valid price point. prices = mkt_client.get_price(pay_request['request']['pricePoint']) # Set up the product for sale. bill_id, seller_product = client.configure_product_for_billing( transaction_uuid, seller_uuid, pay_request['request']['id'], pay_request['request']['name'], # app/product name absolutify(reverse('bango.success')), absolutify(reverse('bango.error')), prices['prices'] ) client.slumber.generic.transaction(transaction_uuid).patch({ 'notes': json.dumps(notes), 'uid_pay': bill_id, 'status': constants.STATUS_PENDING }) except Exception, exc: log.exception('while configuring for payment') etype, val, tb = sys.exc_info() raise exc, None, tb
def start_pay(transaction_uuid, notes, **kw): """ Work with Solitude to begin a Bango payment. This puts the transaction in a state where it's ready to be fulfilled by Bango. """ # Because this is called from views, we get a new transaction every # time. If you re-use this task, you'd want to add some checking about the # transaction state. pay = notes['pay_request'] try: seller_uuid = get_seller_uuid(notes['issuer_key'], pay['request'].get('productData', '')) # Ask the marketplace for a valid price point. prices = mkt_client.get_price(pay['request']['pricePoint']) try: icon_url = (get_icon_url(pay['request']) if settings.USE_PRODUCT_ICONS else None) except: log.exception('Calling get_icon_url') icon_url = None log.info('icon URL for %s: %s' % (transaction_uuid, icon_url)) # Set up the product for sale. bill_id, seller_product = client.configure_product_for_billing( transaction_uuid, seller_uuid, pay['request']['id'], pay['request']['name'], # app/product name absolutify(reverse('bango.success')), absolutify(reverse('bango.error')), prices['prices'], icon_url, ) trans_pk = client.slumber.generic.transaction.get_object( uuid=transaction_uuid)['resource_pk'] client.slumber.generic.transaction(trans_pk).patch({ 'notes': json.dumps(notes), 'uid_pay': bill_id, 'status': constants.STATUS_PENDING }) except Exception, exc: log.exception('while configuring for payment') etype, val, tb = sys.exc_info() raise exc, None, tb
def create_transaction(self, generic_seller, generic_product, provider_product, product_name, transaction_uuid, prices, user_uuid, application_size, source, icon_url, mcc=None, mnc=None): try: data = self.network_data[(mcc, mnc)] except KeyError: raise self.TransactionError('Unknown network: mcc={mcc}; mnc={mnc}' .format(mcc=mcc, mnc=mnc)) country = mobile_codes.mcc(mcc) price = None for pr in prices: # Given a list of all prices + currencies for this price point, # send Boku the one that matches the user's network. if pr['currency'] == data['currency']: price = pr['price'] break if not price: raise self.TransactionError( 'Could not find a price for currency {cur}; ' 'mcc={mcc}; mnc={mnc}'.format(cur=data['currency'], mcc=mcc, mnc=mnc)) provider_trans = self.api.transactions.post({ 'callback_url': absolutify(reverse('provider.success', args=[self.name])), 'country': country.alpha2, # TODO: figure out error callbacks in bug 987843. #'error_url': absolutify(reverse('provider.error', # args=[self.name])), 'price': price, 'seller_uuid': generic_seller['uuid'], 'transaction_uuid': transaction_uuid, 'user_uuid': user_uuid, }) log.info('{pr}: made provider trans {trans}' .format(pr=self.name, trans=provider_trans)) trans = self.slumber.generic.transaction.post({ 'provider': solitude_const.PROVIDERS[self.name], 'seller_product': generic_product['resource_uri'], 'source': solitude_const.PROVIDERS[self.name], 'status': solitude_const.STATUS_PENDING, 'type': solitude_const.TYPE_PAYMENT, 'uuid': transaction_uuid, }) log.info('{pr}: made solitude trans {trans}' .format(pr=self.name, trans=trans)) return provider_trans['transaction_id'], provider_trans['buy_url']
def create_transaction(self, generic_seller, generic_product, provider_product, product_name, transaction_uuid, prices, user_uuid, application_size, source, icon_url, mcc=None, mnc=None): try: data = self.network_data[(mcc, mnc)] except KeyError: raise self.TransactionError( 'Unknown network: mcc={mcc}; mnc={mnc}'.format(mcc=mcc, mnc=mnc)) country = mobile_codes.mcc(mcc) price = None for pr in prices: # Given a list of all prices + currencies for this price point, # send Boku the one that matches the user's network. if pr['currency'] == data['currency']: price = pr['price'] break if not price: raise self.TransactionError( 'Could not find a price for currency {cur}; ' 'mcc={mcc}; mnc={mnc}'.format(cur=data['currency'], mcc=mcc, mnc=mnc)) provider_trans = self.api.transactions.post({ 'callback_url': absolutify(reverse('provider.success', args=[self.name])), 'country': country.alpha2, # TODO: figure out error callbacks in bug 987843. #'error_url': absolutify(reverse('provider.error', # args=[self.name])), 'price': price, 'seller_uuid': generic_seller['uuid'], 'transaction_uuid': transaction_uuid, 'user_uuid': user_uuid, }) log.info('{pr}: made provider trans {trans}'.format( pr=self.name, trans=provider_trans)) trans = self.slumber.generic.transaction.post({ 'provider': solitude_const.PROVIDERS[self.name], 'seller_product': generic_product['resource_uri'], 'source': solitude_const.PROVIDERS[self.name], 'status': solitude_const.STATUS_PENDING, 'type': solitude_const.TYPE_PAYMENT, 'uuid': transaction_uuid, }) log.info('{pr}: made solitude trans {trans}'.format(pr=self.name, trans=trans)) return provider_trans['transaction_id'], provider_trans['buy_url']
def create_transaction(self, generic_seller, generic_product, provider_product, product_name, transaction_uuid, prices, user_uuid, application_size, source, icon_url, mcc=None, mnc=None): # TODO: Maybe make these real values. See bug 941952. # In the case of Zippy, it does not detect any of these values # itself. All other providers will detect these values without # help from Webpay. carrier = 'USA_TMOBILE' region = '123' pay_method = 'OPERATOR' # Note: most providers will use the prices array. price = '0.99' currency = 'EUR' provider_trans = self.api.transactions.post({ 'product_id': provider_product['resource_pk'], 'region': region, 'carrier': carrier, 'price': price, 'currency': currency, 'pay_method': pay_method, 'callback_success_url': absolutify(reverse('pay.callback_success_url')), 'callback_error_url': absolutify(reverse('pay.callback_error_url')), 'ext_transaction_id': transaction_uuid, 'success_url': absolutify(reverse('provider.success', args=[self.name])), 'error_url': absolutify(reverse('provider.error', args=[self.name])), 'product_image_url': icon_url, }) # Note that the old Bango code used to do get-or-create # but I can't tell if we need that or not. Let's wait until it breaks. # See solitude/lib/transactions/models.py trans = self.slumber.generic.transaction.post({ 'uuid': transaction_uuid, 'status': solitude_const.STATUS_PENDING, 'provider': solitude_const.PROVIDERS[self.name], 'seller_product': generic_product['resource_uri'], 'source': solitude_const.PROVIDERS[self.name], 'region': region, 'carrier': carrier, 'type': solitude_const.TYPE_PAYMENT, 'amount': price, 'currency': currency, }) log.info('made solitude trans {trans}'.format(trans=trans)) token = provider_trans['token'] return token, self._formatted_payment_url(token)
def create_transaction(self, generic_seller, generic_product, provider_product, product_name, transaction_uuid, prices, user_uuid, application_size, source, icon_url, mcc=None, mnc=None): try: # Do a sanity check to make sure we're actually on a Boku network. self.network_data[(mcc, mnc)] except KeyError: raise self.TransactionError('Unknown Boku network: ' 'mcc={mcc}; mnc={mnc}'.format(mcc=mcc, mnc=mnc)) country = mobile_codes.mcc(mcc) # TODO: consider using get_price_country here? mcc_region = COUNTRIES[mcc] price = None for mktpl_price in prices: # Given a list of all prices + currencies for this price point, # send Boku the one that matches the user's network/region. if mktpl_price['region'] == mcc_region: price = mktpl_price['price'] break if not price: log.error('No Boku price for region {r}: mcc={mcc}; mnc={mnc} ' 'in prices {pr}'.format(mcc=mcc, mnc=mnc, r=mcc_region, pr=prices)) raise self.TransactionError( 'Could not find a price for region {r}: mcc={mcc}; mnc={mnc}'. format(mcc=mcc, mnc=mnc, r=mcc_region)) provider_trans = self.api.transactions.post({ 'forward_url': absolutify(reverse('provider.wait_to_finish', args=[self.name])), 'callback_url': absolutify(reverse('provider.notification', args=[self.name])), 'country': country.alpha2, # TODO: figure out error callbacks in bug 987843. #'error_url': absolutify(reverse('provider.error', # args=[self.name])), 'price': price, 'seller_uuid': generic_seller['uuid'], 'transaction_uuid': transaction_uuid, 'user_uuid': user_uuid, }) log.info('{pr}: made provider trans {trans}'.format( pr=self.name, trans=provider_trans)) trans = self.slumber.generic.transaction.post({ 'provider': solitude_const.PROVIDERS[self.name], 'seller_product': generic_product['resource_uri'], 'source': solitude_const.PROVIDERS[self.name], 'status': solitude_const.STATUS_PENDING, 'type': solitude_const.TYPE_PAYMENT, 'uuid': transaction_uuid, }) log.info('{pr}: made solitude trans {trans}'.format(pr=self.name, trans=trans)) return provider_trans['transaction_id'], provider_trans['buy_url']
def configure_product_for_billing(self, transaction_uuid, seller_uuid, product_id, product_name, prices, icon_url, user_uuid, application_size, source='unknown', provider=None): """ Start a payment provider transaction to begin the purchase flow. TODO(Kumar): rename this function when we no longer need to maintain the Bango one. """ provider = self.set_provider(provider) try: seller = self.slumber.generic.seller.get_object_or_404( uuid=seller_uuid) except ObjectDoesNotExist: raise SellerNotConfigured('Seller with uuid %s does not exist' % seller_uuid) seller_id = seller['resource_pk'] log.info('transaction %s: seller: %s' % (transaction_uuid, seller_id)) log.info('{provider}: get product for ' 'seller_uuid={uuid} external_id={ext}' .format(provider=provider, uuid=seller_uuid, ext=product_id)) product = None try: product = self.slumber.generic.product.get_object_or_404( external_id=product_id, seller=seller_id, ) log.info('found product {pr}'.format(pr=product)) provider_product = self.provider.products.get_object_or_404( seller_id=seller_uuid, external_id=product_id) log.info('found provider product {pr}'.format(pr=provider_product)) except ObjectDoesNotExist: product, provider_product = self.create_product( product_id, product_name, seller, provider=provider, generic_product=product) # TODO: Make these real values. See bug 941952. carrier = 'USA_TMOBILE' region = '123' pay_method = 'OPERATOR' price = '0.99' currency = 'EUR' provider_trans = self.provider.transactions.post({ 'product_id': provider_product['resource_pk'], 'region': region, 'carrier': carrier, 'price': price, 'currency': currency, 'pay_method': pay_method, 'callback_success_url': absolutify( reverse('pay.callback_success_url')), 'callback_error_url': absolutify( reverse('pay.callback_error_url')), 'ext_transaction_id': transaction_uuid, 'success_url': absolutify(reverse('provider.success', args=[provider])), 'error_url': absolutify(reverse('provider.error', args=[provider])), 'product_image_url': icon_url, }) log.info('made provider trans {trans}'.format(trans=provider_trans)) # Note that the old Bango code used to do get-or-create # but I can't tell if we need that or not. Let's wait until it breaks. # See solitude/lib/transactions/models.py trans = self.slumber.generic.transaction.post({ 'uuid': transaction_uuid, 'status': solitude_const.STATUS_PENDING, 'provider': solitude_const.PROVIDERS[provider], 'seller_product': product['resource_uri'], 'source': solitude_const.PROVIDERS[provider], 'region': region, 'carrier': carrier, 'type': solitude_const.TYPE_PAYMENT, 'amount': price, 'currency': currency, }) log.info('made solitude trans {trans}'.format(trans=trans)) return provider_trans['token'], seller_id
def create_transaction(self, generic_buyer, generic_seller, generic_product, provider_product, provider_seller_uuid, product_name, transaction_uuid, prices, user_uuid, application_size, source, icon_url, mcc=None, mnc=None): # TODO: Maybe make these real values. See bug 941952. # In the case of Zippy, it does not detect any of these values # itself. All other providers will detect these values without # help from Webpay. carrier = 'FAKE' region = 'CAN' pay_method = 'OPERATOR' # How do we decide what price to show? Normally Bango does this # by deciding based on region detection. For our purposes, let's just # choose the USD price. # # USD is set up by default in zamboni, so this will work out of the # box. for p in prices: if p['region'] == countries.COUNTRY_DETAILS['USA']['id']: currency, price = p['currency'], p['price'] break else: raise ValueError('No USD price tier defined.') provider_trans = self.api.transactions.post({ 'product_id': provider_product[self.name]['uuid'], 'region': region, 'carrier': carrier, 'price': price, 'currency': currency, 'pay_method': pay_method, 'callback_success_url': absolutify( reverse('api:pay.callback_success_url')), 'callback_error_url': absolutify( reverse('api:pay.callback_error_url')), 'ext_transaction_id': transaction_uuid, 'success_url': absolutify(reverse('provider.success', args=[self.name])), 'error_url': absolutify(reverse('provider.error', args=[self.name])), 'product_image_url': icon_url, }) # Note that the old Bango code used to do get-or-create # but I can't tell if we need that or not. Let's wait until it breaks. # See solitude/lib/transactions/models.py trans = self.slumber.generic.transaction.post({ 'uuid': transaction_uuid, 'status': solitude_const.STATUS_PENDING, 'provider': solitude_const.PROVIDERS[self.name], 'buyer': generic_buyer['resource_uri'], 'seller': generic_seller['resource_uri'], 'seller_product': generic_product['resource_uri'], 'source': source, 'region': region, 'carrier': carrier, 'type': solitude_const.TYPE_PAYMENT, 'amount': price, 'currency': currency, }) log.info('made solitude trans {trans}'.format(trans=trans)) token = provider_trans['token'] return token, self._formatted_payment_url(token)