def handle_successful_payout(self): payout = self.mangopay.get_pay_out(self.resource_id) if payout["DebitedWalletId"] == "FEES_EUR": logger.info("Mangopay fees payout. Ignoring") return if payout["Status"] == "SUCCEEDED": wallet = self.mangopay.get_wallet(payout["DebitedWalletId"]) user = self.get_user_by_mangopay_id(wallet["Owners"][0]) amount = "{0:.2f}".format(payout["CreditedFunds"]["Amount"] / 100.0) currency = payout["CreditedFunds"]["Currency"] send_mail( region=self.get_region(), template="mails/payments/successful_payout.html", context={ "amount": amount, "currency": currency }, recipient_list=[user.email], subject="Beträge wurden überwiesen", ) else: logger.error( "Weird, hook status different than real payout status")
def approve_user(self, request, queryset): buyer_group = Group.objects.get(name="buyer") seller_group = Group.objects.get(name="seller") queryset = queryset.exclude(groups__in=[buyer_group]) count = 0 for count, user in enumerate(queryset, start=1): user.groups.add(buyer_group) if user.declared_as_seller: user.groups.add(seller_group) user.save() send_mail( region=user.region, subject="Ihr Account wurde aktiviert.", recipient_list=[user.email], template="mails/users/user_activated.html", ) if not user.mangopay_user_id: user.send_task( f"/users/{user.id}/mangopay/create", queue_name="mangopay-create-account", http_method="POST", ) self.message_user(request, f"{count} users activated")
def post(self, request, user_id, format=None): user = User.objects.get(id=user_id) tomorrow = (timezone.now() + datetime.timedelta(days=1)).date() jobs_queryset = (Job.objects.prefetch_related("detours").filter( detours__route__user_id=user_id, order_item__latest_delivery_date__gt=tomorrow, user__isnull=True, order_item__order__processed=False, ).annotate(detour=Min("detours__length")).order_by( "order_item__latest_delivery_date").distinct()) if jobs_queryset.count() < 1: logger.debug(f"No jobs for user {user_id}") return Response(status=status.HTTP_204_NO_CONTENT) send_mail( request.region, subject="Routes", recipient_list=[user.email], template="mails/jobs/notification_email.html", context={ "jobs": jobs_queryset, "CURRENCY_SYMBOL": CURRENT_CURRENCY_SYMBOL }, ) return Response(status=status.HTTP_204_NO_CONTENT)
def handle_valid_kyc_document(self, document: Dict): user = self.get_user_by_mangopay_id(document["UserId"]) document_human_name = self.document_human_name(document) if self.is_validation_complete(document["UserId"]): logger.info("Validation complete.") self.store_validation_level(user) send_mail( region=self.get_region(), subject="Account-Verfizierung wurde erfolgreich abgeschlossen", recipient_list=[user.email], template="mails/documents/document_validated.html", context={ "document_name": document_human_name, "validation_complete": True, "document_url": self.document_copy_url(document), }, ) else: send_mail( region=self.get_region(), subject=f"{document_human_name} wurde akzeptiert", recipient_list=[user.email], template="mails/documents/document_validated.html", context={ "document_name": document_human_name, "validation_complete": False, }, )
def test_use_logo_from_region_model_in_email(traidoo_region, mailoutbox, image_file): image_file._committed = True traidoo_region.mail_logo = image_file traidoo_region.save() send_mail(traidoo_region, "Foo", ["*****@*****.**"], "mails/unsold_items.html", {}) soup = bs4.BeautifulSoup(mailoutbox[-1].body, features="html.parser") assert "png" in soup.find_all("img")[0].attrs["src"]
def test_use_global_platform_mail_if_local_is_missing(traidoo_settings, mailoutbox, traidoo_region): setting = traidoo_region.setting setting.platform_user = None setting.save() send_mail(traidoo_region, "Foo", ["*****@*****.**"], "mails/unsold_items.html", {}) assert mailoutbox[-1].subject == "Foo" assert mailoutbox[-1].from_email == settings.DEFAULT_FROM_EMAIL
def handle_failed_kyc_document(self, document: Dict): user = self.get_user_by_mangopay_id(document["UserId"]) document_human_name = self.document_human_name(document) send_mail( region=self.get_region(), subject=f"{document_human_name} wurde abgelehnt", recipient_list=[user.email], template="mails/documents/document_rejected.html", context={ "reason_type": document["RefusedReasonType"], "reason_message": document["RefusedReasonMessage"], "document_name": document_human_name, "document_url": self.document_copy_url(document), }, )
def handle_failed_payin(self): payin = self.mangopay.get_pay_in(self.resource_id) if payin["Status"] == "FAILED": body = ( f"Payin {self.resource_id} failed. Error message: " f"{payin['ResultMessage']}. Check mangopay for further details." ) logger.debug(f"handle_failed_payin: {body}") send_mail( region=self.get_region(), recipient_list=get_admin_emails(), subject="Fehler bei der Verarbeitung der Zahlung", template="mails/generic.html", context={"body": body}, )
def email_has_changed(sender, instance, created, **kwargs): # TODO: move it to view if created: return if instance.tracker.has_changed("email"): send_mail( region=instance.region, subject="Ihre E-Mail-Adresse wurde geändert", recipient_list=[instance.email], template="mails/users/email_change.html", context={ "old_email": instance.tracker.previous("email"), "new_email": instance.email, }, )
def post(self, request, format=None): serializer = NewPasswordSerializer(data=request.data) if not serializer.is_valid(): return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) user = serializer.user user.set_password(serializer.data["new_password"]) user.save() send_mail( region=request.region, subject="Ihr Password wurde geändert", recipient_list=[user.email], template="mails/users/password_change.html", ) return Response(status=status.HTTP_204_NO_CONTENT)
def post(self, request, format=None): user = self.request.user if not user.is_email_verified: uid = urlsafe_base64_encode(force_bytes(user.pk)) token = default_token_generator.make_token(user) send_mail( region=request.region, subject="Bitte bestätigen Sie Ihre E-Mail-Adresse", recipient_list=[user.email], template="mails/users/verify_email.html", context={ "domain": Site.objects.get_current().domain, "url": f"registration/{uid}/{token}", }, ) return Response(status=status.HTTP_204_NO_CONTENT)
def post(self, request, seller_id, format=None): unsold_items_by_product = collections.defaultdict(dict) now = timezone.localtime( timezone.now(), pytz.timezone(settings.USER_DEFAULT_TIME_ZONE)) items = (Item.objects.select_related("product").annotate( items_available=Coalesce(Sum("product__items__quantity"), 0)).filter( items_available__gt=0, product__seller_id=seller_id, latest_delivery_date__lt=now.date(), )) for item in items: try: count = unsold_items_by_product[item.product.id]["count"] except KeyError: count = 0 unsold_items_by_product[item.product.id] = { "name": item.product.name, "count": count + 1, } items.delete() if unsold_items_by_product: send_mail( region=request.region, subject="Abgelaufene Produkte", recipient_list=[User.objects.get(id=seller_id).email], template="mails/unsold_items.html", context={ "items_by_product": dict(unsold_items_by_product), "base_url": Site.objects.get_current().domain, }, ) return Response()
def post(self, request: Request, order_id: str, email: str): documents = Document.objects.filter(order_id=order_id) order = Order.objects.get(id=order_id) documents_to_send = [ document for document in documents if email in document.receivers_emails ] attachments_as_blobs = [ self.bucket.blob(document.blob_name) for document in documents_to_send ] send_log = DocumentSendLog.objects.select_for_update().get( order_id=order_id, email=email ) if not send_log.sent: send_mail( region=order.region, subject=f"Bestellbestätigung für #{order.id}", recipient_list=[email], template="mails/generic.html", context={ "body": ( f"Ihre Unterlagen für die Bestellung #{order.id} finden " f"Sie im Anhang dieser E-Mail" ) }, attachments=[ ( trans(blob.name.split("/")[-1]), blob.download_as_string(), blob.content_type, ) for blob in attachments_as_blobs ], ) send_log.sent = True send_log.save(update_fields=["sent", "updated_at"]) return Response()
def post(self, request, format=None): serializer = EmailSerializer(data=request.data) if not serializer.is_valid(): return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) try: user = User.objects.get(email=serializer.validated_data["email"]) except User.DoesNotExist: pass else: send_mail( region=self.request.region, subject="Password reset", recipient_list=[user.email], template="mails/users/password_reset.html", context={ "domain": Site.objects.get_current().domain, "url": f"password/reset/{user.generate_uid()}/{user.generate_token()}", }, ) return Response(status=status.HTTP_204_NO_CONTENT)
def handle_failed_payout(self): payout = self.mangopay.get_pay_out(self.resource_id) if payout["Status"] != "SUCCEEDED": wallet = self.mangopay.get_wallet(payout["DebitedWalletId"]) user = self.get_user_by_mangopay_id( mangopay_user_id=wallet["Owners"][0]) amount = "{0:.2f}".format(payout["CreditedFunds"]["Amount"] / 100.0) currency = payout["CreditedFunds"]["Currency"] result_message = payout["ResultMessage"] send_mail( region=self.get_region(), template="mails/payments/failed_payout.html", context={ "amount": amount, "currency": currency, "result_message": result_message, }, recipient_list=[user.email], subject="Eine Überweisung ist fehlgeschlagen", ) else: logger.error( "Weird, hook status different than real payout status")
def _process_as_direct_pay_in(self, pay_in: Dict): try: document = Document.objects.select_related("order").get( mangopay_payin_id=self.resource_id) except Document.DoesNotExist: send_mail( region=self.get_region(), subject="Fehler bei der Verarbeitung der Zahlung", recipient_list=get_admin_emails(), template="mails/generic.html", context={ "body": f"Document related to payin {self.resource_id} not found. " }, ) return if document.paid: logger.warning( (f"Invoice `{document.id}` already paid. Probably " f"duplicated notification for payin {self.resource_id} " f"from mangopay. ")) return order = document.order pay_in_currency = pay_in["DebitedFunds"]["Currency"] if pay_in_currency != "EUR": raise PaymentError( (f"Wrong currency `{pay_in_currency}` for payin " f"{ self.resource_id}, expected EUR. ")) if document.document_type == document.TYPES.get_value( "order_confirmation_buyer"): pay_in_amount = pay_in["DebitedFunds"]["Amount"] if pay_in_amount < document.price_gross_cents and not self.skip_checks: logger.debug( f"Document gross cents: {document.price_gross_cents}") send_mail( region=self.get_region(), subject="Fehler bei der Verarbeitung der Zahlung", recipient_list=get_admin_emails(), template="mails/generic.html", context={ "body": (f"Wrong amount received in payin {self.resource_id} " f"for document {document.id}. Expected (in cents) " f"`{document.price_gross_cents}`, but received " f"`{pay_in_amount}`\n") }, ) return Response("Falied") elif pay_in_amount > document.price_gross_cents and not self.skip_checks: logger.debug( f"Document gross cents: {document.price_gross_cents}") send_mail( region=self.get_region(), subject="Client paid too much", recipient_list=get_admin_emails(), template="mails/generic.html", context={ "body": (f"Too much received in payin {self.resource_id} for " f"document {document.id}. Expected (in cents) " f"`{document.price_gross_cents}`, but received " f"`{pay_in_amount}`\n") }, ) # Get unpaid documents for the order order_invoices = Document.objects.filter( order_id=order.id, paid=False, # Do not process platform invoices document_type__in=[ Document.TYPES.get_value("logistics_invoice"), Document.TYPES.get_value("producer_invoice"), ], ).order_by("-document_type") for invoice in order_invoices: logger.debug("Paying invoice {}".format(invoice.id)) self.pay_for_invoice_from_pay_in(pay_in, invoice) global_platform_user = get_platform_user_for_order(order.id) global_platform_user_wallet = self.get_user_wallet( global_platform_user.mangopay_user_id) self.pay_local_platform_owner( order.id, order.buyer.mangopay_user_id, pay_in["CreditedWalletId"], global_platform_user_wallet, global_platform_user.id, ) # Pay combined platform fee in one transfer from buyer wallet try: self.pay_for_platform( pay_in, order.id, order.buyer.mangopay_user_id, order.total_price, global_platform_user_wallet, global_platform_user, fees_charged_at_payin=True, ) except OperationalError as error: logger.warning( f"Other process is trying to pay for platform: `{error}`") self.try_to_set_order_as_paid(order) else: raise PaymentError( "Received payment for unexpected document type {}, payin id: {}" .format(document.document_type, self.resource_id))
def handle_successful_pay_in(self): pay_in = self.mangopay.get_pay_in(self.resource_id) if pay_in["Status"] != "SUCCEEDED" and not self.skip_checks: send_mail( region=self.get_region(), subject="Fehler bei der Verarbeitung der Zahlung", recipient_list=get_admin_emails(), template="mails/generic.html", context={ "body": (f"Successfully received {self.resource_id} hook, but " f"actual status is `{pay_in['Status']}`. Check with Mangopay details" ) }, ) return banking_alias_id = pay_in.get("BankingAliasId") if not banking_alias_id: # Old order return self._process_as_direct_pay_in(pay_in) banking_alias = self.mangopay.get_banking_alias(banking_alias_id) wallet_id = banking_alias["WalletId"] mangopay_user_id = banking_alias["CreditedUserId"] buyer = User.objects.get(mangopay_user_id=mangopay_user_id) order_confirmation_documents = ( Document.objects.select_related("order").filter( paid=False, document_type=Document.TYPES.get_value( "order_confirmation_buyer"), buyer__user_id=buyer.id, payment_reference=None, ).order_by("created_at")) for order_confirmation_document in order_confirmation_documents: wallet = self.mangopay.get_wallet(wallet_id) if not sufficient_wallet_balance_for_order( order_confirmation_document.order_id, buyer.id, wallet): logger.info( f"No more cash in wallet to pay for order {order_confirmation_document.order_id}" ) break order_invoices = ( Document.objects.select_related("order").filter( order_id=order_confirmation_document.order.id, paid=False, # Do not pay platform invoice here, since there's extra calculation document_type__in=[ Document.TYPES.get_value("logistics_invoice"), Document.TYPES.get_value("producer_invoice"), ], ).order_by("-document_type")) for invoice in order_invoices: logger.debug("Paying invoice {}".format(invoice.id)) self.pay_for_invoice_from_pay_in(pay_in, invoice) # Take the first platform invoice to get platform user information global_platform_user = get_platform_user_for_order( order_confirmation_document.order_id) if not global_platform_user.mangopay_user_id: error_message = ( f"Cannot process payin `{self.resource_id}` and pay for platform." f"Platform user `{global_platform_user.id}` does not have mangopay account. " f"Please create an account and process trigger payin processing again." ) send_mail( region=self.get_region(), subject="Fehler bei der Verarbeitung der Zahlung", recipient_list=get_admin_emails(), template="mails/generic.html", context={"body": error_message}, ) return global_platform_user_wallet = self.get_user_wallet( global_platform_user.mangopay_user_id) self.pay_local_platform_owner( order_confirmation_document.order_id, order_confirmation_document.order.buyer.mangopay_user_id, pay_in["CreditedWalletId"], global_platform_user_wallet, global_platform_user.id, ) # Pay combined platform fee in one transfer from buyer wallet try: self.pay_for_platform( pay_in, order_confirmation_document.order.id, order_confirmation_document.order.buyer.mangopay_user_id, total_order_value=order_confirmation_document.price_gross, global_platform_user_wallet=global_platform_user_wallet, global_platform_user=global_platform_user, ) except OperationalError as error: logger.warning( f"Other process is trying to pay for platform: `{error}`") self.try_to_set_order_as_paid(order_confirmation_document.order) wallet = self.mangopay.get_wallet(wallet_id) if wallet["Balance"]["Amount"] > 0: error_message = ( f"After processing payin `{self.resource_id}` " f"buyer with mangopay id {mangopay_user_id} still has positive wallet" f"balance {wallet['Balance']['Amount']} cents") send_mail( region=self.get_region(), subject="User has extra cash in wallet", recipient_list=get_admin_emails(), template="mails/generic.html", context={"body": error_message}, ) return
def pay_local_platform_owner( self, order_id: int, buyer_mangopay_user_id: str, buyer_mangopay_wallet_id: str, global_platform_user_wallet: dict, global_platform_user_id: int, ) -> Decimal: """ Tries to pay local platform owner :param global_platform_user_id: :param global_platform_user_wallet: :param buyer_mangopay_wallet_id: :param buyer_mangopay_user_id: :param order_id: :return: float value, amount paid for local platform owner """ try: credit_note_for_local_platform_owner = Document.objects.get( order_id=order_id, document_type=Document.TYPES.get_value("credit_note"), paid=False, seller__user_id=global_platform_user_id, ) except Document.DoesNotExist: logger.info( f"No credit notes issued by global platform owner f{global_platform_user_id}" ) return Decimal("0") local_platform_owner = User.objects.get( id=credit_note_for_local_platform_owner.buyer["user_id"]) if not local_platform_owner.mangopay_user_id: error_message = ( f"Cannot pay local platform owner his share {credit_note_for_local_platform_owner.price_gross} " f"because local platform owner `{local_platform_owner.id}` does not have mangopay account. " f"Funds will be transfered to global platform owner") send_mail( region=self.get_region(), subject="Fehler bei der Verarbeitung der Zahlung", recipient_list=get_admin_emails(), template="mails/generic.html", context={"body": error_message}, ) # we are not using _pay_for_document() since we do not want to mark document as paid self.mangopay.transfer( buyer_mangopay_user_id, buyer_mangopay_wallet_id, global_platform_user_wallet["Id"], amount=credit_note_for_local_platform_owner.price_gross, fees=0, tag=credit_note_for_local_platform_owner.mangopay_tag, ) return Decimal( str(credit_note_for_local_platform_owner.price_gross)) local_platform_owner_wallet = self.get_user_wallet( local_platform_owner.mangopay_user_id) try: pay_for_document( document=credit_note_for_local_platform_owner, author_id=buyer_mangopay_user_id, source_wallet_id=buyer_mangopay_wallet_id, destination_wallet_id=local_platform_owner_wallet["Id"], amount=credit_note_for_local_platform_owner.price_gross, ) except MangopayTransferError as mangopay_error: error_message = (f"Cannot pay local platform owner." f"Mangopay transfer error {mangopay_error}") send_mail( region=self.get_region(), subject="Fehler bei der Verarbeitung der Zahlung", template="mails/generic.html", recipient_list=get_admin_emails(), context={"body": error_message}, ) return Decimal("0") except DuplicateTransferError: return Decimal("0") self.send_task( f"/mangopay/cron/payouts/{local_platform_owner.mangopay_user_id}", queue_name="mangopay-payouts", http_method="POST", payload={ "order_id": order_id, "amount": credit_note_for_local_platform_owner.price_gross, }, headers={ "Region": local_platform_owner.region.slug, "Content-Type": "application/json", }, ) return Decimal(str(credit_note_for_local_platform_owner.price_gross))
def test_add_regional_reply_to(traidoo_region, mailoutbox): send_mail(traidoo_region, "Foo", ["*****@*****.**"], "mails/unsold_items.html", {}) assert f"intercom+{traidoo_region.name}@example.com" in mailoutbox[ -1].reply_to
def pay_for_platform( self, pay_in: Dict, order_id: int, buyer_mangopay_user_id: str, total_order_value: float, global_platform_user_wallet: dict, global_platform_user: User, fees_charged_at_payin=False, ): platform_invoices = Document.objects.select_for_update( nowait=True).filter( order_id=order_id, paid=False, document_type__in=[ Document.TYPES.get_value("platform_invoice"), Document.TYPES.get_value("buyer_platform_invoice"), ], ) invoice = platform_invoices.first() if not invoice: return local_platform_fee_due = calculate_local_platform_fee_for_order( order_id, global_platform_user.id) buyer_mangopay_wallet_id = pay_in["CreditedWalletId"] global_platform_user_mangopay_id = global_platform_user_wallet[ "Owners"][0] total_unpaid_platform_invoices_value = calculate_platform_fee_for_order( order_id) mangopay_fees = self.mangopay_fees(total_order_value) mangopay_fees = Decimal(str(mangopay_fees)) amount_to_transfer_to_global_platform_owner = ( total_unpaid_platform_invoices_value - local_platform_fee_due) amount_to_payout_from_global_platform_owner_wallet = ( amount_to_transfer_to_global_platform_owner - mangopay_fees) if fees_charged_at_payin: amount_to_transfer_to_global_platform_owner -= mangopay_fees amount_to_transfer_to_global_platform_owner = ( amount_to_transfer_to_global_platform_owner.quantize( Decimal(".01"), "ROUND_HALF_UP")) amount_to_transfer_to_global_platform_owner = float( amount_to_transfer_to_global_platform_owner) try: # not using `pay_for_document` to avoid nested transactions self.mangopay.transfer( buyer_mangopay_user_id, buyer_mangopay_wallet_id, global_platform_user_wallet["Id"], amount=amount_to_transfer_to_global_platform_owner, fees=float(mangopay_fees) if not fees_charged_at_payin else 0, tag=invoice.mangopay_tag, ) except MangopayTransferError as transfer_error: error_message = ( f"Transfer from buyer wallet {buyer_mangopay_wallet_id} to " f"platform wallet {global_platform_user_wallet['Id']} failed. " f"Mangopay error: {transfer_error}. ") send_mail( region=self.get_region(), subject="Fehler bei der Verarbeitung der Zahlung", template="mails/generic.html", context={"body": error_message}, recipient_list=get_admin_emails(), ) return for invoice in platform_invoices: invoice.paid = True invoice.save(update_fields=["paid", "updated_at"]) send_mail( region=self.get_region(), subject=f"Zahlung erhalten für Auftrag #{invoice.order_id}", template="mails/payments/successful_payin.html", context={ "currency": CURRENT_CURRENCY_CODE, "amount": f"{invoice.price_gross:.2f}", "buyer_company_name": invoice.buyer["company_name"], "document_name": invoice.__class__.__name__, "order_number": invoice.order_id, }, recipient_list=[invoice.seller["email"]], ) self.send_task( f"/mangopay/cron/payouts/{global_platform_user_mangopay_id}", queue_name="mangopay-payouts", http_method="POST", payload={ "order_id": invoice.order_id, "amount": float(amount_to_payout_from_global_platform_owner_wallet), }, headers={ "Region": invoice.order.region.slug, "Content-Type": "application/json", }, )
def test_use_footer_from_region_model_in_email(traidoo_region, mailoutbox): send_mail(traidoo_region, "Foo", ["*****@*****.**"], "mails/unsold_items.html", {}) assert traidoo_region.mail_footer in mailoutbox[-1].body
def test_use_regional_website_slogan_in_email(traidoo_region, mailoutbox): send_mail(traidoo_region, "Foo", ["*****@*****.**"], "mails/unsold_items.html", {}) assert traidoo_region.website_slogan in mailoutbox[-1].body
def create(self, request, *args, **kwargs): serializer = RegistrationSerializer(data=request.data) serializer.is_valid(raise_exception=True) user_data = serializer.validated_data user_password = user_data.pop("password") user_image = user_data.pop("image", None) user_business_license = user_data.pop("business_license", None) kyc_documents = { "identity_proof": KycDocument.Name.IDENTITY_PROOF.name, "shareholder_declaration": KycDocument.Name.SHAREHOLDER_DECLARATION.name, "articles_of_association": KycDocument.Name.ARTICLES_OF_ASSOCIATION.name, "registration_proof": KycDocument.Name.REGISTRATION_PROOF.name, "address_proof": KycDocument.Name.ADDRESS_PROOF.name, } documents_data = {key: user_data.pop(key, None) for key in kyc_documents.keys()} user = User.objects.create(**user_data, region=request.region) user.set_password(user_password) # Workaround to get instance ID in private_image_upload_to(). if user_image: user.image = user_image if user_business_license: user.business_license = user_business_license user.save() DeliveryAddress.objects.create( user=user, street=user.street, zip=user.zip, city=user.city, company_name=user.company_name, ) for key, value in documents_data.items(): if value: document = KycDocument.objects.create( user=user, name=kyc_documents.get(key) ) # Workaround to get instance ID in private_image_upload_to(). document.file = value document.save() uid = urlsafe_base64_encode(force_bytes(user.pk)) token = default_token_generator.make_token(user) send_mail( region=request.region, subject="Bitte bestätigen Sie Ihre E-Mail-Adresse", recipient_list=[user.email], template="mails/users/verify_email.html", context={ "domain": Site.objects.get_current().domain, "url": f"registration/{uid}/{token}", }, ) location = reverse("admin:users_user_changelist") send_mail( region=request.region, subject="Neuer Nutzer registriert", recipient_list=settings.REAL_ADMINS, template="mails/users/new_user_registered.html", context={ "domain": self.request.get_host(), "location": location, "email": user.email, }, ) self.send_task( f"/users/{user.id}/mangopay/create", queue_name="mangopay-create-account", http_method="POST", schedule_time=10, headers={ "Region": request.region.slug, "Content-Type": "application/json", }, ) return response.Response(status=status.HTTP_201_CREATED)
def pay_for_invoice_from_pay_in(self, pay_in: Dict, invoice: Document): seller_id = invoice.seller["user_id"] buyer_id = invoice.buyer["user_id"] seller_profile = User.objects.get(pk=seller_id) if not seller_profile.mangopay_user_id: error_message = ( f"Cannot process payin `{self.resource_id}`. Seller " f"`{seller_id}` does not have mangopay account. " f"Please create an account and contact support to trigger order processing again" ) send_mail( region=self.get_region(), subject="Fehler bei der Verarbeitung der Zahlung", template="mails/generic.html", context={"body": error_message}, recipient_list=get_admin_emails(), ) return seller_mangopay_wallet = self.get_user_wallet( seller_profile.mangopay_user_id) buyer_profile = User.objects.get(pk=buyer_id) buyer_mangopay_wallet_id = pay_in["CreditedWalletId"] if invoice.document_type == invoice.TYPES.get_value( "producer_invoice"): # Producer gets paid for invoice minus gross value of platform # invoice for his sale platform_invoice_for_this_producer = Document.objects.get( order_id=invoice.order.id, document_type=Document.TYPES.get_value("platform_invoice"), buyer__user_id=seller_id, ) amount = Decimal(str(invoice.price_gross)) - Decimal( str(platform_invoice_for_this_producer.price_gross)) else: amount = Decimal(str(invoice.price_gross)) amount = amount.quantize(Decimal(".01"), "ROUND_HALF_UP") amount = float(amount) try: pay_for_document( document=invoice, author_id=buyer_profile.mangopay_user_id, source_wallet_id=buyer_mangopay_wallet_id, destination_wallet_id=seller_mangopay_wallet["Id"], amount=amount, fees=0, ) except MangopayTransferError as mangopay_error: error_message = ( f"Transfer from buyer wallet {buyer_mangopay_wallet_id} to " f"seller wallet {seller_mangopay_wallet['Id']} failed. " f"Mangopay error: {mangopay_error}. " "Please contact support to investigate issue and trigger processing again." f"Affected document {invoice.id}") send_mail( region=self.get_region(), subject="Fehler bei der Verarbeitung der Zahlung", template="mails/generic.html", context={"body": error_message}, recipient_list=get_admin_emails(), ) return except DuplicateTransferError as error: logger.exception(error) return send_mail( region=self.get_region(), subject=f"Zahlung erhalten für Auftrag #{invoice.order_id}", template="mails/payments/successful_payin.html", context={ "currency": CURRENT_CURRENCY_CODE, "amount": f"{amount:.2f}", "buyer_company_name": invoice.buyer["company_name"], "document_name": invoice.__class__.__name__, "order_number": invoice.order_id, }, recipient_list=[invoice.seller["email"]], ) self.send_task( f"/mangopay/cron/payouts/{seller_profile.mangopay_user_id}", queue_name="mangopay-payouts", http_method="POST", payload={ "order_id": invoice.order_id, "amount": amount }, headers={ "Region": invoice.order.region.slug, "Content-Type": "application/json", }, )