def refund_reason(request, contribution, wizard): addon = contribution.addon if not 'request' in wizard.get_progress(): return redirect('support', contribution.pk, 'request') if contribution.transaction_id is None: messages.error(request, _('A refund cannot be applied for yet. Please try again later. ' 'If this error persists contact [email protected].')) paypal_log.info('Refund requested for contribution with no ' 'transaction_id: %r' % contribution.pk) return redirect('account.purchases') if contribution.is_instant_refund(): try: paypal.refund(contribution.paykey) except PaypalError, e: paypal_log.error('Paypal error with refund', exc_info=True) messages.error(request, _('There was an error with your instant ' 'refund.')) contribution.record_failed_refund(e) return redirect('account.purchases') refund = contribution.enqueue_refund(amo.REFUND_APPROVED_INSTANT) paypal_log.info('Refund %r issued for contribution %r' % (refund.pk, contribution.pk)) # Note: we have to wait for PayPal to issue an IPN before it's # completely refunded. messages.success(request, _('Refund is being processed.')) return redirect('account.purchases')
def refund_reason(request, contribution, wizard): addon = contribution.addon if not 'request' in wizard.get_progress(): return redirect('users.support', contribution.pk, 'request') if contribution.is_instant_refund(): paypal.refund(contribution.paykey) paypal_log.info('Refund issued for contribution %r' % contribution.pk) # Note: we have to wait for PayPal to issue an IPN before it's # completely refunded. messages.success(request, _('Refund is being processed.')) return redirect('users.purchases') form = forms.ContactForm(request.POST or None) if request.method == 'POST' and form.is_valid(): url = absolutify(urlparams(addon.get_dev_url('issue_refund'), transaction_id=contribution.transaction_id)) template = jingo.render_to_string(request, wizard.tpl('emails/refund-request.txt'), context={'addon': addon, 'form': form, 'user': request.amo_user, 'contribution': contribution, 'refund_url': url}) log.info('Refund request sent by user: %s for addon: %s' % (request.amo_user.pk, addon.pk)) # L10n: %s is the addon name. send_mail(_(u'New Refund Request for %s' % addon.name), template, settings.NOBODY_EMAIL, [smart_str(addon.support_email)]) return redirect(reverse('users.support', args=[contribution.pk, 'refund-sent'])) return wizard.render(request, wizard.tpl('refund.html'), {'form': form})
def refund_reason(request, contribution, wizard): if not contribution.can_we_refund(): return http.HttpResponseForbidden() addon = contribution.addon if not 'request' in wizard.get_progress(): return redirect('support', contribution.pk, 'request') if contribution.transaction_id is None: messages.error(request, _('A refund cannot be applied for yet. Please try again later. ' 'If this error persists contact [email protected].')) paypal_log.info('Refund requested for contribution with no ' 'transaction_id: %r' % contribution.pk) return redirect('account.purchases') if contribution.is_instant_refund(): try: paypal.refund(contribution.paykey) except PaypalError: paypal_log.error('Paypal error with refund', exc_info=True) messages.error(request, _('There was an error with your instant ' 'refund.')) return redirect('account.purchases') refund = contribution.enqueue_refund(amo.REFUND_APPROVED_INSTANT) paypal_log.info('Refund %r issued for contribution %r' % (refund.pk, contribution.pk)) # Note: we have to wait for PayPal to issue an IPN before it's # completely refunded. messages.success(request, _('Refund is being processed.')) return redirect('account.purchases') form = forms.ContactForm(request.POST or None) if request.method == 'POST' and form.is_valid(): reason = form.cleaned_data['text'] template = jingo.render_to_string(request, wizard.tpl('emails/refund-request.txt'), context={'product': addon, 'form': form, 'user': request.amo_user, 'contribution': contribution, 'refund_url': contribution.get_absolute_refund_url(), 'refund_reason': reason}) log.info('Refund request sent by user: %s for addon: %s' % (request.amo_user.pk, addon.pk)) # L10n: %s is the app name. support_mail(_(u'New Refund Request for %s' % addon.name), template, sender=settings.NOBODY_EMAIL, recipients=[smart_str(addon.support_email)]) # Add this refund request to the queue. contribution.enqueue_refund(amo.REFUND_PENDING, reason) return redirect(reverse('support', args=[contribution.pk, 'refund-sent'])) return wizard.render(request, wizard.tpl('refund.html'), {'product': addon, 'contribution': contribution, 'form': form, 'title': _('Request Refund')})
def refund_reason(request, contribution, wizard): addon = contribution.addon if not "request" in wizard.get_progress(): return redirect("users.support", contribution.pk, "request") if contribution.transaction_id is None: messages.error( request, _( "A refund cannot be applied for yet. Please try again" " later. If this error persists contact " "[email protected]." ), ) paypal_log.info("Refund requested for contribution with no " "transaction_id: %r" % (contribution.pk,)) return redirect("users.purchases") if contribution.is_instant_refund(): paypal.refund(contribution.paykey) # TODO: Consider requiring a refund reason for instant refunds. refund = contribution.enqueue_refund(amo.REFUND_APPROVED_INSTANT) paypal_log.info("Refund %r issued for contribution %r" % (refund.pk, contribution.pk)) # Note: we have to wait for PayPal to issue an IPN before it's # completely refunded. messages.success(request, _("Refund is being processed.")) return redirect("users.purchases") form = forms.ContactForm(request.POST or None) if request.method == "POST" and form.is_valid(): reason = form.cleaned_data["text"] template = jingo.render_to_string( request, wizard.tpl("emails/refund-request.txt"), context={ "addon": addon, "form": form, "user": request.amo_user, "contribution": contribution, "refund_url": contribution.get_absolute_refund_url(), "refund_reason": reason, }, ) log.info("Refund request sent by user: %s for addon: %s" % (request.amo_user.pk, addon.pk)) # L10n: %s is the addon name. send_mail( _(u"New Refund Request for %s" % addon.name), template, settings.NOBODY_EMAIL, [smart_str(addon.support_email)], ) # Add this refund request to the queue. contribution.enqueue_refund(amo.REFUND_PENDING, reason) return redirect(reverse("users.support", args=[contribution.pk, "refund-sent"])) return wizard.render(request, wizard.tpl("refund.html"), {"form": form})
def refund_reason(request, contribution, wizard): addon = contribution.addon if not 'request' in wizard.get_progress(): return redirect('users.support', contribution.pk, 'request') if contribution.transaction_id is None: messages.error( request, _('A refund cannot be applied for yet. Please try again' ' later. If this error persists contact ' '[email protected].')) paypal_log.info('Refund requested for contribution with no ' 'transaction_id: %r' % (contribution.pk, )) return redirect('users.purchases') if contribution.is_instant_refund(): paypal.refund(contribution.paykey) # TODO: Consider requiring a refund reason for instant refunds. refund = contribution.enqueue_refund(amo.REFUND_APPROVED_INSTANT) paypal_log.info('Refund %r issued for contribution %r' % (refund.pk, contribution.pk)) # Note: we have to wait for PayPal to issue an IPN before it's # completely refunded. messages.success(request, _('Refund is being processed.')) return redirect('users.purchases') form = forms.ContactForm(request.POST or None) if request.method == 'POST' and form.is_valid(): reason = form.cleaned_data['text'] template = jingo.render_to_string( request, wizard.tpl('emails/refund-request.txt'), context={ 'addon': addon, 'form': form, 'user': request.amo_user, 'contribution': contribution, 'refund_url': contribution.get_absolute_refund_url(), 'refund_reason': reason }) log.info('Refund request sent by user: %s for addon: %s' % (request.amo_user.pk, addon.pk)) # L10n: %s is the addon name. send_mail(_(u'New Refund Request for %s' % addon.name), template, settings.NOBODY_EMAIL, [smart_str(addon.support_email)]) # Add this refund request to the queue. contribution.enqueue_refund(amo.REFUND_PENDING, reason) return redirect( reverse('users.support', args=[contribution.pk, 'refund-sent'])) return wizard.render(request, wizard.tpl('refund.html'), {'form': form})
def issue_refund(request, addon_id, addon, webapp=False): txn_id = request.REQUEST.get("transaction_id") if not txn_id: raise http.Http404 form_enabled = True contribution = get_object_or_404( Contribution, transaction_id=txn_id, type__in=[amo.CONTRIB_PURCHASE, amo.CONTRIB_INAPP] ) if hasattr(contribution, "refund") and contribution.refund.status not in (amo.REFUND_PENDING, amo.REFUND_FAILED): # If it's not pending, we've already taken action. messages.error(request, _("Refund already processed.")) form_enabled = False elif request.method == "POST": if "issue" in request.POST: if waffle.flag_is_active(request, "solitude-payments"): try: response = client.post_refund(data={"uuid": contribution.transaction_id}) except client.Error, e: contribution.record_failed_refund(e) paypal_log.error("Refund failed for: %s" % txn_id, exc_info=True) messages.error(request, _("There was an error with " "the refund.")) return redirect(addon.get_dev_url("refunds")) results = response["response"] else: # TODO(solitude): remove this. try: results = paypal.refund(contribution.paykey) except PaypalError, e: contribution.record_failed_refund(e) paypal_log.error("Refund failed for: %s" % txn_id, exc_info=True) messages.error(request, _("There was an error with " "the refund.")) return redirect(addon.get_dev_url("refunds")) for res in results: if res["refundStatus"] == "ALREADY_REVERSED_OR_REFUNDED": paypal_log.debug( "Refund attempt for already-refunded paykey: %s, %s" % (contribution.paykey, res["receiver.email"]) ) messages.error(request, _("Refund was previously issued; " "no action taken.")) return redirect(addon.get_dev_url("refunds")) elif res["refundStatus"] == "NO_API_ACCESS_TO_RECEIVER": paypal_log.debug( "Refund attempt for product %s with no " "refund token: %s, %s" % (contribution.addon.pk, contribution.paykey, res["receiver.email"]) ) messages.error( request, _("A refund can't be issued at this time. We've " "notified an admin; please try again later."), ) return redirect(addon.get_dev_url("refunds")) contribution.mail_approved() amo.log(amo.LOG.REFUND_GRANTED, addon, contribution.user) refund = contribution.enqueue_refund(amo.REFUND_APPROVED) paypal_log.info("Refund %r issued for contribution %r" % (refund.pk, contribution.pk)) messages.success(request, _("Refund issued."))
def issue_refund(request, addon_id, addon, webapp=False): txn_id = request.REQUEST.get('transaction_id') if not txn_id: raise http.Http404 form_enabled = True contribution = get_object_or_404(Contribution, transaction_id=txn_id, type__in=[amo.CONTRIB_PURCHASE, amo.CONTRIB_INAPP]) if (hasattr(contribution, 'refund') and contribution.refund.status not in (amo.REFUND_PENDING, amo.REFUND_FAILED)): # If it's not pending, we've already taken action. messages.error(request, _('Refund already processed.')) form_enabled = False elif request.method == 'POST': if 'issue' in request.POST: try: results = paypal.refund(contribution.paykey) except PaypalError, e: contribution.record_failed_refund(e) paypal_log.error('Refund failed for: %s' % txn_id, exc_info=True) messages.error(request, _('There was an error with ' 'the refund.')) return redirect(addon.get_dev_url('refunds')) for res in results: if res['refundStatus'] == 'ALREADY_REVERSED_OR_REFUNDED': paypal_log.debug( 'Refund attempt for already-refunded paykey: %s, %s' % (contribution.paykey, res['receiver.email'])) messages.error(request, _('Refund was previously issued; ' 'no action taken.')) return redirect(addon.get_dev_url('refunds')) elif res['refundStatus'] == 'NO_API_ACCESS_TO_RECEIVER': paypal_log.debug('Refund attempt for product %s with no ' 'refund token: %s, %s' % (contribution.addon.pk, contribution.paykey, res['receiver.email'])) messages.error(request, _("A refund can't be issued at this time. We've " "notified an admin; please try again later.")) return redirect(addon.get_dev_url('refunds')) contribution.mail_approved() refund = contribution.enqueue_refund(amo.REFUND_APPROVED) paypal_log.info('Refund %r issued for contribution %r' % (refund.pk, contribution.pk)) messages.success(request, _('Refund issued.')) else: contribution.mail_declined() # TODO: Consider requiring a rejection reason for declined refunds. refund = contribution.enqueue_refund(amo.REFUND_DECLINED) paypal_log.info('Refund %r declined for contribution %r' % (refund.pk, contribution.pk)) messages.success(request, _('Refund declined.')) return redirect(addon.get_dev_url('refunds'))
def refund_reason(request, contribution, wizard): addon = contribution.addon if not 'request' in wizard.get_progress(): return redirect('users.support', contribution.pk, 'request') if contribution.transaction_id is None: messages.error(request, _('A refund cannot be applied for yet. Please try again' ' later. If this error persists contact ' '[email protected].')) paypal_log.info('Refund requested for contribution with no ' 'transaction_id: %r' % (contribution.pk,)) return redirect('users.purchases') if contribution.is_instant_refund(): paypal.refund(contribution.paykey) # TODO: Consider requiring a refund reason for instant refunds. refund = contribution.enqueue_refund(amo.REFUND_APPROVED_INSTANT) paypal_log.info('Refund %r issued for contribution %r' % (refund.pk, contribution.pk)) # Note: we have to wait for PayPal to issue an IPN before it's # completely refunded. messages.success(request, _('Refund is being processed.')) return redirect('users.purchases') form = forms.ContactForm(request.POST or None) if request.method == 'POST' and form.is_valid(): reason = form.cleaned_data['text'] template = jingo.render_to_string(request, wizard.tpl('emails/refund-request.txt'), context={'addon': addon, 'form': form, 'user': request.amo_user, 'contribution': contribution, 'refund_url': contribution.get_absolute_refund_url(), 'refund_reason': reason}) log.info('Refund request sent by user: %s for addon: %s' % (request.amo_user.pk, addon.pk)) # L10n: %s is the addon name. send_mail(_(u'New Refund Request for %s' % addon.name), template, settings.NOBODY_EMAIL, [smart_str(addon.support_email)]) # Add this refund request to the queue. contribution.enqueue_refund(amo.REFUND_PENDING, reason) return redirect(reverse('users.support', args=[contribution.pk, 'refund-sent'])) return wizard.render(request, wizard.tpl('refund.html'), {'form': form})
def refund_reason(request, contribution, wizard): addon = contribution.addon if not 'request' in wizard.get_progress(): return redirect('support', contribution.pk, 'request') if contribution.transaction_id is None: messages.error( request, _('A refund cannot be applied for yet. Please try again later. ' 'If this error persists contact [email protected].')) paypal_log.info('Refund requested for contribution with no ' 'transaction_id: %r' % contribution.pk) return redirect('account.purchases') if contribution.is_refunded(): messages.error(request, _('This has already been refunded.')) paypal_log.info('Already refunded: %s' % contribution.pk) return redirect('account.purchases') if contribution.is_instant_refund(): if waffle.flag_is_active(request, 'solitude-payments'): try: client.post_refund(data={'uuid': contribution.transaction_id}) except client.Error, e: paypal_log.error('Paypal error with refund', exc_info=True) messages.error( request, _('There was an error with your ' 'instant refund.')) contribution.record_failed_refund(e, request.amo_user) return redirect('account.purchases') else: # TODO(solitude): remove this. try: paypal.refund(contribution.paykey) except PaypalError, e: paypal_log.error('Paypal error with refund', exc_info=True) messages.error( request, _('There was an error with your ' 'instant refund.')) contribution.record_failed_refund(e, request.amo_user) return redirect('account.purchases')
def refund_reason(request, contribution, wizard): addon = contribution.addon if not "request" in wizard.get_progress(): return redirect("support", contribution.pk, "request") if contribution.transaction_id is None: messages.error( request, _( "A refund cannot be applied for yet. Please try again later. " "If this error persists contact [email protected]." ), ) paypal_log.info("Refund requested for contribution with no " "transaction_id: %r" % contribution.pk) return redirect("account.purchases") if contribution.is_refunded(): messages.error(request, _("This has already been refunded.")) paypal_log.info("Already refunded: %s" % contribution.pk) return redirect("account.purchases") if contribution.is_instant_refund(): if waffle.flag_is_active(request, "solitude-payments"): try: client.post_refund(data={"uuid": contribution.transaction_id}) except client.Error, e: paypal_log.error("Paypal error with refund", exc_info=True) messages.error(request, _("There was an error with your " "instant refund.")) contribution.record_failed_refund(e) return redirect("account.purchases") else: # TODO(solitude): remove this. try: paypal.refund(contribution.paykey) except PaypalError, e: paypal_log.error("Paypal error with refund", exc_info=True) messages.error(request, _("There was an error with your " "instant refund.")) contribution.record_failed_refund(e) return redirect("account.purchases")
def refund_reason(request, contribution, wizard): addon = contribution.addon if not 'request' in wizard.get_progress(): return redirect('support', contribution.pk, 'request') if contribution.transaction_id is None: messages.error(request, _('A refund cannot be applied for yet. Please try again later. ' 'If this error persists contact [email protected].')) paypal_log.info('Refund requested for contribution with no ' 'transaction_id: %r' % contribution.pk) return redirect('account.purchases') if contribution.is_refunded(): messages.error(request, _('This has already been refunded.')) paypal_log.info('Already refunded: %s' % contribution.pk) return redirect('account.purchases') if contribution.is_instant_refund(): if waffle.flag_is_active(request, 'solitude-payments'): try: client.post_refund(data={'uuid': contribution.transaction_id}) except client.Error, e: paypal_log.error('Paypal error with refund', exc_info=True) messages.error(request, _('There was an error with your ' 'instant refund.')) contribution.record_failed_refund(e, request.amo_user) return redirect('account.purchases') else: # TODO(solitude): remove this. try: paypal.refund(contribution.paykey) except PaypalError, e: paypal_log.error('Paypal error with refund', exc_info=True) messages.error(request, _('There was an error with your ' 'instant refund.')) contribution.record_failed_refund(e, request.amo_user) return redirect('account.purchases')
def refund_reason(request, contribution, wizard): addon = contribution.addon if not 'request' in wizard.get_progress(): return redirect('support', contribution.pk, 'request') if contribution.transaction_id is None: messages.error(request, _('A refund cannot be applied for yet. Please try again later. ' 'If this error persists contact [email protected].')) paypal_log.info('Refund requested for contribution with no ' 'transaction_id: %r' % contribution.pk) return redirect('account.purchases') if contribution.is_refunded(): messages.error(request, _('This has already been refunded.')) paypal_log.info('Already refunded: %s' % contribution.pk) return redirect('account.purchases') if contribution.is_instant_refund(): try: paypal.refund(contribution.paykey) except PaypalError, e: paypal_log.error('Paypal error with refund', exc_info=True) messages.error(request, _('There was an error with your instant ' 'refund.')) contribution.record_failed_refund(e) return redirect('account.purchases') refund = contribution.enqueue_refund(amo.REFUND_APPROVED_INSTANT) paypal_log.info('Refund %r issued for contribution %r' % (refund.pk, contribution.pk)) # Note: we have to wait for PayPal to issue an IPN before it's # completely refunded. messages.success(request, _('Refund is being processed.')) amo.log(amo.LOG.REFUND_INSTANT, addon) return redirect('account.purchases')
def test_refund_error(self, _call): _call.side_effect = paypal.PaypalError with self.assertRaises(paypal.PaypalError): paypal.refund("fake-paykey")
def test_refund_success(self, opener): """ Making refund requests returns the refund info. """ opener.return_value = StringIO(good_refund_string) eq_(paypal.refund("fake-paykey"), good_refund_data)
def test_refund_wrong_status(self, opener): opener.return_value = StringIO(error_refund_string) with self.assertRaises(paypal.PaypalError): paypal.refund("fake-paykey")
def issue_refund(request, addon_id, addon, webapp=False): txn_id = request.REQUEST.get('transaction_id') if not txn_id: raise http.Http404 form_enabled = True contribution = get_object_or_404( Contribution, transaction_id=txn_id, type__in=[amo.CONTRIB_PURCHASE, amo.CONTRIB_INAPP]) if (hasattr(contribution, 'refund') and contribution.refund.status not in (amo.REFUND_PENDING, amo.REFUND_FAILED)): # If it's not pending, we've already taken action. messages.error(request, _('Refund already processed.')) form_enabled = False elif request.method == 'POST': if 'issue' in request.POST: try: results = paypal.refund(contribution.paykey) except PaypalError, e: contribution.record_failed_refund(e) paypal_log.error('Refund failed for: %s' % txn_id, exc_info=True) messages.error(request, _('There was an error with ' 'the refund.')) return redirect(addon.get_dev_url('refunds')) for res in results: if res['refundStatus'] == 'ALREADY_REVERSED_OR_REFUNDED': paypal_log.debug( 'Refund attempt for already-refunded paykey: %s, %s' % (contribution.paykey, res['receiver.email'])) messages.error( request, _('Refund was previously issued; ' 'no action taken.')) return redirect(addon.get_dev_url('refunds')) elif res['refundStatus'] == 'NO_API_ACCESS_TO_RECEIVER': paypal_log.debug( 'Refund attempt for product %s with no ' 'refund token: %s, %s' % (contribution.addon.pk, contribution.paykey, res['receiver.email'])) messages.error( request, _("A refund can't be issued at this time. We've " "notified an admin; please try again later.")) return redirect(addon.get_dev_url('refunds')) contribution.mail_approved() amo.log(amo.LOG.REFUND_GRANTED, addon, contribution.user) refund = contribution.enqueue_refund(amo.REFUND_APPROVED) paypal_log.info('Refund %r issued for contribution %r' % (refund.pk, contribution.pk)) messages.success(request, _('Refund issued.')) else: contribution.mail_declined() amo.log(amo.LOG.REFUND_DECLINED, addon, contribution.user) # TODO: Consider requiring a rejection reason for declined refunds. refund = contribution.enqueue_refund(amo.REFUND_DECLINED) paypal_log.info('Refund %r declined for contribution %r' % (refund.pk, contribution.pk)) messages.success(request, _('Refund declined.')) return redirect(addon.get_dev_url('refunds'))
def test_refund_success(self, opener): """ Making refund requests returns the refund info. """ opener.return_value.text = good_refund_string eq_(paypal.refund('fake-paykey'), good_refund_data)
def test_refund_wrong_status(self, opener): opener.return_value.text = error_refund_string with self.assertRaises(paypal.PaypalError): paypal.refund('fake-paykey')
def test_refundFailure(self, opener): opener.return_value = StringIO(error_refund_string) with self.assertRaises(paypal.PaypalError): paypal.refund('fake-txnid')
def test_refundSuccess(self, opener): """ Making refund requests returns the refund info. """ opener.return_value = StringIO(good_refund_string) eq_(paypal.refund('fake-txnid'), good_refund_data)
def test_refund_no_refund_token(self, opener): opener.return_value.text = no_token_refund_string d = paypal.refund('fake-paykey') eq_(d[0]['refundStatus'], 'NO_API_ACCESS_TO_RECEIVER')
def test_refund_processing_failed(self, opener): opener.return_value.text = processing_failed_refund_string d = paypal.refund('fake-paykey') eq_(d[0]['refundStatus'], 'NO_API_ACCESS_TO_RECEIVER')
def test_refund_processing_failed(self, opener): opener.return_value = StringIO(processing_failed_refund_string) d = paypal.refund("fake-paykey") eq_(d[0]["refundStatus"], "NO_API_ACCESS_TO_RECEIVER")
def issue_refund(request, addon_id, addon, webapp=False): txn_id = request.REQUEST.get("transaction_id") if not txn_id: raise http.Http404 form_enabled = True contribution = get_object_or_404(Contribution, transaction_id=txn_id, type=amo.CONTRIB_PURCHASE) if hasattr(contribution, "refund") and contribution.refund.status != amo.REFUND_PENDING: # If it's not pending, we've already taken action. messages.error(request, _("Refund already processed.")) form_enabled = False elif request.method == "POST": if "issue" in request.POST: try: results = paypal.refund(contribution.paykey) except PaypalError: paypal_log.error("Refund failed for: %s" % txn_id, exc_info=True) messages.error(request, _("There was an error with " "the refund.")) return redirect(addon.get_dev_url("refunds")) for res in results: if res["refundStatus"] == "ALREADY_REVERSED_OR_REFUNDED": paypal_log.debug( "Refund attempt for already-refunded paykey: %s, %s" % (contribution.paykey, res["receiver.email"]) ) messages.error(request, _("Refund was previously issued; " "no action taken.")) return redirect(addon.get_dev_url("refunds")) elif res["refundStatus"] == "NO_API_ACCESS_TO_RECEIVER": paypal_log.debug( "Refund attempt for product %s with no " "refund token: %s, %s" % (contribution.addon.pk, contribution.paykey, res["receiver.email"]) ) messages.error( request, _("A refund can't be issued at this time. We've " "notified an admin; please try again later."), ) return redirect(addon.get_dev_url("refunds")) contribution.mail_approved() refund = contribution.enqueue_refund(amo.REFUND_APPROVED) paypal_log.info("Refund %r issued for contribution %r" % (refund.pk, contribution.pk)) messages.success(request, _("Refund issued.")) else: contribution.mail_declined() # TODO: Consider requiring a rejection reason for declined refunds. refund = contribution.enqueue_refund(amo.REFUND_DECLINED) paypal_log.info("Refund %r declined for contribution %r" % (refund.pk, contribution.pk)) messages.success(request, _("Refund declined.")) return redirect(addon.get_dev_url("refunds")) return jingo.render( request, "developers/payments/issue-refund.html", { "enabled": form_enabled, "contribution": contribution, "addon": addon, "webapp": webapp, "transaction_id": txn_id, }, )
def test_refunded_already(self, opener): opener.return_value.text = already_refunded_string eq_(paypal.refund('fake-paykey')[0]['refundStatus'], 'ALREADY_REVERSED_OR_REFUNDED')
def test_refunded_already(self, opener): opener.return_value = StringIO(already_refunded_string) eq_(paypal.refund("fake-paykey")[0]["refundStatus"], "ALREADY_REVERSED_OR_REFUNDED")
def test_refunded_already(self, opener): opener.return_value.text = already_refunded_string eq_( paypal.refund('fake-paykey')[0]['refundStatus'], 'ALREADY_REVERSED_OR_REFUNDED')
def test_refund_error(self, _call): _call.side_effect = paypal.PaypalError with self.assertRaises(paypal.PaypalError): paypal.refund('fake-paykey')
def test_refund_no_refund_token(self, opener): opener.return_value = StringIO(no_token_refund_string) d = paypal.refund("fake-paykey") eq_(d[0]["refundStatus"], "NO_API_ACCESS_TO_RECEIVER")