def formatDonationAmount(amount, currency_code): currency = getCurrencyDictAt(currency_code) if currency['setting']['number_decimals'] != 0: # amount must now be a whole integer since number_decimals is at most 2 amount *= 100 formatted_str = str(int(amount)) return formatted_str
def __init__(self, *args, subscription=None, **kwargs): super().__init__(*args, **kwargs) currency_set = getCurrencyDictAt(subscription.currency) if not subscription: raise ValueError(_('Please provide a subscription object')) self.fields["subscription_id"].initial = subscription.profile_id self.fields["subscription_id"].widget.attrs['disabled'] = True self.fields["currency"].initial = html.unescape( currency_set['admin_label']) self.fields["currency"].widget.attrs['disabled'] = True self.fields["recurring_amount"] = forms.DecimalField( label=_('Recurring donation amount'), min_value=Decimal('0.01'), decimal_places=getCurrencyDictAt( subscription.currency)['setting']['number_decimals']) self.fields[ "recurring_amount"].initial = subscription.recurring_amount if currency_set[ 'setting']['number_decimals'] != 0 else int( subscription.recurring_amount)
def format_payment_amount(amount, currency_code): """ When submitting a new payment, use the donation's currency to format the donation amount . Amount needs to be formatted into 12 digit format with leading zero. Minor unit appended to the last digit depending on number of Minor unit specified in ISO 4217. https://developer.2c2p.com/docs/payment-requestresponse-parameters """ currency = getCurrencyDictAt(currency_code) decnum = currency['setting']['number_decimals'] amount_str = str(int(Decimal(amount) * 10**decnum)) if decnum != 0 else str(int(amount)) formatted = "{:0>12}".format(amount_str) return formatted
def redirect_to_gateway_url(self): """ Overriding parent implementation as 2C2P has to receive a form post from client browser. See docs https://developer.2c2p.com/docs/payment-requestresponse-parameters on recurring parameters behavior """ data = {} data['version'] = REDIRECT_API_VERSION data['merchant_id'] = self.settings.merchant_id data['order_id'] = self.donation.transaction_id data['currency'] = getCurrencyDictAt(self.donation.currency)['code'] # Beware: self.donation.donation_amount param is str in type data['amount'] = format_payment_amount(self.donation.donation_amount, self.donation.currency) # Apr 20 Tested result_url_1/2 working (such that merchant portal no need manual setting) after follow up with 2C2P Sum (an internal 2C2P settings needs to be turned on by them) # todo: Apr 21 2C2P server is not firing back the request from the new recurring payments (need follow up with Sum again) data['result_url_1'] = reverse_with_site_url( 'donations:return-from-2c2p') data['result_url_2'] = reverse_with_site_url( 'donations:verify-2c2p-response') data['user_defined_1'] = str(self.donation.id) if self.donation.is_recurring: data['payment_description'] = _( 'Recurring Donation for %(site)s') % { 'site': get_site_name() } data['request_3ds'] = 'Y' data['recurring'] = 'Y' data['order_prefix'] = gen_order_prefix_2c2p() data['recurring_amount'] = format_payment_amount( self.donation.donation_amount, self.donation.currency) data['allow_accumulate'] = 'N' data['recurring_count'] = 0 data['payment_option'] = 'A' # - daily recurring for testing data['recurring_interval'] = 1 data['charge_next_date'] = getNextDateFromRecurringInterval( data['recurring_interval'], '%d%m%Y') # - monthly recurring(normal behavior) # getRecurringDateNextMonth requires the superuser to set the timezone first # data['charge_on_date'] = getRecurringDateNextMonth('%d%m') # append order_prefix to donation metas for distinguishment # dpmeta = DonationPaymentMeta( # donation=self.donation, field_key='order_prefix', field_value=data['order_prefix']) # dpmeta.save() else: data['payment_description'] = _( 'Onetime Donation for %(site)s') % { 'site': get_site_name() } params = '' for key in getRequestParamOrder(): if key in data.keys(): params += str(data[key]) # python 3.6 code data['hash_value'] = hmac.new(bytes(self.settings.secret_key, 'utf-8'), bytes(params, 'utf-8'), hashlib.sha256).hexdigest() return render(self.request, 'donations/redirection_2c2p_form.html', { 'action': self.base_gateway_redirect_url(), 'data': data })
def formatDonationAmountFromGateway(amount_str, currency_code): currency = getCurrencyDictAt(currency_code) if currency['setting']['number_decimals'] != 0: # need to divide amount by 100 return Decimal(amount_str)/100 return Decimal(amount_str)