def complete_gold_purchase(secret, transaction_id, payer_email, payer_id, subscription_id, pennies, months, goldtype, buyer, recipient, signed, giftmessage, comment): """After receiving a message from a payment processor, apply gold. Shared endpoint for all payment processing systems. Validation of gold purchase (sender, recipient, etc.) should happen before hitting this. """ gold_recipient = recipient or buyer with gold_lock(gold_recipient): gold_recipient._sync_latest() days = days_from_months(months) if goldtype in ('onetime', 'autorenew'): admintools.engolden(buyer, days) if goldtype == 'onetime': subject = "thanks for buying reddit gold!" if g.lounge_reddit: message = strings.lounge_msg else: message = ":)" else: subject = "your reddit gold has been renewed!" message = ("see the details of your subscription on " "[your userpage](/u/%s)" % buyer.name) elif goldtype == 'creddits': buyer._incr('gold_creddits', months) subject = "thanks for buying creddits!" message = ("To spend them, visit http://%s/gold or your favorite " "person's userpage." % (g.domain)) elif goldtype == 'gift': send_gift(buyer, recipient, months, days, signed, giftmessage, comment) subject = "thanks for giving reddit gold!" message = "Your gift to %s has been delivered." % recipient.name status = 'processed' secret_pieces = [goldtype] if goldtype == 'gift': secret_pieces.append(recipient.name) secret_pieces.append(secret) secret = '-'.join(secret_pieces) try: create_claimed_gold(transaction_id, payer_email, payer_id, pennies, days, secret, buyer._id, c.start_time, subscr_id=subscription_id, status=status) except IntegrityError: g.log.error('gold: got duplicate gold transaction') try: message = append_random_bottlecap_phrase(message) send_system_message(buyer, subject, message, distinguished='gold-auto') except MessageError: g.log.error('complete_gold_purchase: could not send system message')
def complete_gold_purchase(secret, transaction_id, payer_email, payer_id, subscription_id, pennies, months, goldtype, buyer, recipient, signed, giftmessage, comment): """After receiving a message from a payment processor, apply gold. Shared endpoint for all payment processing systems. Validation of gold purchase (sender, recipient, etc.) should happen before hitting this. """ gold_recipient = recipient or buyer with gold_lock(gold_recipient): gold_recipient._sync_latest() days = days_from_months(months) if goldtype in ('onetime', 'autorenew'): admintools.engolden(buyer, days) if goldtype == 'onetime': subject = "thanks for buying reddit gold!" if g.lounge_reddit: lounge_url = "/r/" + g.lounge_reddit message = strings.lounge_msg % dict(link=lounge_url) else: message = ":)" else: subject = "your reddit gold has been renewed!" message = ("see the details of your subscription on " "[your userpage](/u/%s)" % buyer.name) elif goldtype == 'creddits': buyer._incr('gold_creddits', months) subject = "thanks for buying creddits!" message = ("To spend them, visit http://%s/gold or your favorite " "person's userpage." % (g.domain)) elif goldtype == 'gift': send_gift(buyer, recipient, months, days, signed, giftmessage, comment) subject = "thanks for giving reddit gold!" message = "Your gift to %s has been delivered." % recipient.name status = 'processed' secret_pieces = [goldtype] if goldtype == 'gift': secret_pieces.append(recipient.name) secret_pieces.append(secret) secret = '-'.join(secret_pieces) try: create_claimed_gold(transaction_id, payer_email, payer_id, pennies, days, secret, buyer._id, c.start_time, subscr_id=subscription_id, status=status) except IntegrityError: g.log.error('gold: got duplicate gold transaction') try: send_system_message(buyer, subject, message) except MessageError: g.log.error('complete_gold_purchase: could not send system message')
def send_gift(buyer, recipient, months, days, signed, giftmessage, thing_fullname): admintools.engolden(recipient, days) if thing_fullname: thing = Thing._by_fullname(thing_fullname, data=True) thing._gild(buyer) else: thing = None if signed: sender = buyer.name md_sender = "[%s](/user/%s)" % (sender, sender) else: sender = _("An anonymous redditor") md_sender = _("An anonymous redditor") create_gift_gold(buyer._id, recipient._id, days, c.start_time, signed) if months == 1: amount = "a month" else: amount = "%d months" % months if not thing: subject = _( 'Let there be gold! %s just sent you reddit gold!') % sender message = strings.youve_got_gold % dict(sender=md_sender, amount=amount) if giftmessage and giftmessage.strip(): message += "\n\n" + strings.giftgold_note + giftmessage + '\n\n----' else: url = thing.make_permalink_slow() if isinstance(thing, Comment): subject = _('Your comment has been gilded!') message = strings.youve_been_gilded_comment % {'url': url} else: subject = _('Your submission has been gilded!') message = strings.youve_been_gilded_link % {'url': url} message += '\n\n' + strings.gold_benefits_msg if g.lounge_reddit: message += '\n* ' + strings.lounge_msg message = append_random_bottlecap_phrase(message) try: send_system_message(recipient, subject, message, distinguished='gold-auto') except MessageError: g.log.error('send_gift: could not send system message') g.log.info("%s gifted %s to %s" % (buyer.name, amount, recipient.name)) return thing
def send_gift(buyer, recipient, months, days, signed, giftmessage, thing_fullname): admintools.engolden(recipient, days) if thing_fullname: thing = Thing._by_fullname(thing_fullname, data=True) thing._gild(buyer) else: thing = None if signed: sender = buyer.name md_sender = "[%s](/user/%s)" % (sender, sender) else: sender = _("An anonymous redditor") md_sender = _("An anonymous redditor") create_gift_gold(buyer._id, recipient._id, days, c.start_time, signed) if months == 1: amount = "a month" else: amount = "%d months" % months if not thing: subject = _( 'Let there be gold! %s just sent you reddit gold!') % sender message = strings.youve_got_gold % dict( sender=md_sender, amount=amount) if giftmessage and giftmessage.strip(): message += "\n\n" + strings.giftgold_note + giftmessage + '\n\n----' else: url = thing.make_permalink_slow() if isinstance(thing, Comment): subject = _('Your comment has been gilded!') message = strings.youve_been_gilded_comment % {'url': url} else: subject = _('Your submission has been gilded!') message = strings.youve_been_gilded_link % {'url': url} message += '\n\n' + strings.gold_benefits_msg if g.lounge_reddit: message += '\n* ' + strings.lounge_msg message = append_random_bottlecap_phrase(message) try: send_system_message( recipient, subject, message, distinguished='gold-auto') except MessageError: g.log.error('send_gift: could not send system message') g.log.info("%s gifted %s to %s" % (buyer.name, amount, recipient.name)) return thing
def send_gift(buyer, recipient, months, days, signed, giftmessage, comment_id): admintools.engolden(recipient, days) if comment_id: comment = Thing._by_fullname(comment_id, data=True) comment._gild(buyer) else: comment = None if signed: sender = buyer.name md_sender = "[%s](/user/%s)" % (sender, sender) else: sender = _("An anonymous redditor") md_sender = _("An anonymous redditor") create_gift_gold(buyer._id, recipient._id, days, c.start_time, signed) if months == 1: amount = "a month" else: amount = "%d months" % months if not comment: subject = _( 'Let there be gold! %s just sent you reddit gold!') % sender message = strings.youve_got_gold % dict(sender=md_sender, amount=amount) if giftmessage and giftmessage.strip(): message += "\n\n" + strings.giftgold_note + giftmessage + '\n\n----' else: subject = _('Your comment has been gilded.') message = strings.youve_got_comment_gold % dict( url=comment.make_permalink_slow(), ) message += '\n\n' + strings.gold_benefits_msg message += '\n\n' + strings.lounge_msg try: send_system_message(recipient, subject, message) except MessageError: g.log.error('send_gift: could not send system message') g.log.info("%s gifted %s to %s" % (buyer.name, amount, recipient.name)) return comment
def send_gift(buyer, recipient, months, days, signed, giftmessage, comment_id): admintools.engolden(recipient, days) if comment_id: comment = Thing._by_fullname(comment_id, data=True) comment._gild(buyer) else: comment = None if signed: sender = buyer.name md_sender = "[%s](/user/%s)" % (sender, sender) else: sender = _("An anonymous redditor") md_sender = _("An anonymous redditor") create_gift_gold (buyer._id, recipient._id, days, c.start_time, signed) if months == 1: amount = "a month" else: amount = "%d months" % months if not comment: subject = _('Let there be gold! %s just sent you reddit gold!') % sender message = strings.youve_got_gold % dict(sender=md_sender, amount=amount) if giftmessage and giftmessage.strip(): message += "\n\n" + strings.giftgold_note + giftmessage + '\n\n----' else: subject = _('Your comment has been gilded.') message = strings.youve_got_comment_gold % dict( url=comment.make_permalink_slow(), ) message += '\n\n' + strings.gold_benefits_msg message += '\n\n' + strings.lounge_msg try: send_system_message(recipient, subject, message) except MessageError: g.log.error('send_gift: could not send system message') g.log.info("%s gifted %s to %s" % (buyer.name, amount, recipient.name)) return comment
def send_gift(buyer, recipient, months, days, signed, giftmessage, comment_id): admintools.engolden(recipient, days) if comment_id: comment = Thing._by_fullname(comment_id, data=True) comment._gild(buyer) else: comment = None if signed: sender = buyer.name md_sender = "[%s](/user/%s)" % (sender, sender) else: sender = "someone" md_sender = "An anonymous lightnet user" create_gift_gold(buyer._id, recipient._id, days, c.start_time, signed) if months == 1: amount = "a month" else: amount = "%d months" % months if not comment: message = strings.youve_got_gold % dict(sender=md_sender, amount=amount) if giftmessage and giftmessage.strip(): message += "\n\n" + strings.giftgold_note + giftmessage + "\n\n----" else: message = strings.youve_got_comment_gold % dict(url=comment.make_permalink_slow()) message += "\n\n" + strings.gold_benefits_msg message += "\n\n" + strings.lounge_msg % {"link": "/space/" + g.lounge_reddit} subject = sender + " just sent you reddit gold!" try: send_system_message(recipient, subject, message) except MessageError: g.log.error("send_gift: could not send system message") g.log.info("%s gifted %s to %s" % (buyer.name, amount, recipient.name)) return comment
def send_gift(buyer, recipient, months, days, signed, giftmessage, comment_id): admintools.engolden(recipient, days) if comment_id: comment = Thing._by_fullname(comment_id, data=True) comment._gild(buyer) else: comment = None if signed: sender = buyer.name md_sender = "[%s](/user/%s)" % (sender, sender) else: sender = "someone" md_sender = "An anonymous redditor" create_gift_gold (buyer._id, recipient._id, days, c.start_time, signed) if months == 1: amount = "a month" else: amount = "%d months" % months if not comment: message = strings.youve_got_gold % dict(sender=md_sender, amount=amount) if giftmessage and giftmessage.strip(): message += "\n\n" + strings.giftgold_note + giftmessage else: message = strings.youve_got_comment_gold % dict( url=comment.make_permalink_slow(), ) subject = sender + " just sent you reddit gold!" send_system_message(recipient, subject, message) g.log.info("%s gifted %s to %s" % (buyer.name, amount, recipient.name)) return comment
def finish(self, parameters, txn_id, payer_email, paying_id, subscr_id, custom, pennies, months, days): blob_key, payment_blob = get_blob(custom) buyer_id = payment_blob.get('account_id', None) if not buyer_id: dump_parameters(parameters) raise ValueError("No buyer_id in IPN/GC with custom='%s'" % custom) try: buyer = Account._byID(buyer_id) except NotFound: dump_parameters(parameters) raise ValueError("Invalid buyer_id %d in IPN/GC with custom='%s'" % (buyer_id, custom)) if subscr_id: buyer.gold_subscr_id = subscr_id instagift = False if payment_blob['goldtype'] in ('autorenew', 'onetime'): admintools.engolden(buyer, days) subject = _("thanks for buying reddit gold!") if g.lounge_reddit: lounge_url = "/r/" + g.lounge_reddit message = strings.lounge_msg % dict(link=lounge_url) else: message = ":)" elif payment_blob['goldtype'] == 'creddits': buyer._incr("gold_creddits", months) buyer._commit() subject = _("thanks for buying creddits!") message = _("To spend them, visit [/gold](/gold) or your favorite person's userpage.") elif payment_blob['goldtype'] == 'gift': recipient_name = payment_blob.get('recipient', None) try: recipient = Account._by_name(recipient_name) except NotFound: dump_parameters(parameters) raise ValueError("Invalid recipient_name %s in IPN/GC with custom='%s'" % (recipient_name, custom)) signed = payment_blob.get("signed", False) giftmessage = _force_unicode(payment_blob.get("giftmessage", "")) comment_id = payment_blob.get("comment") send_gift(buyer, recipient, months, days, signed, giftmessage, comment_id) instagift = True subject = _("thanks for giving reddit gold!") message = _("Your gift to %s has been delivered." % recipient.name) else: dump_parameters(parameters) raise ValueError("Got status '%s' in IPN/GC" % payment_blob['status']) # Reuse the old "secret" column as a place to record the goldtype # and "custom", just in case we need to debug it later or something secret = payment_blob['goldtype'] + "-" + custom if instagift: status="instagift" else: status="processed" create_claimed_gold(txn_id, payer_email, paying_id, pennies, days, secret, buyer_id, c.start_time, subscr_id, status=status) send_system_message(buyer, subject, message) payment_blob["status"] = "processed" g.hardcache.set(blob_key, payment_blob, 86400 * 30)
def complete_gold_purchase(cls, webhook): """After receiving a message from a payment processor, apply gold. Shared endpoint for all payment processing systems. Validation of gold purchase (sender, recipient, etc.) should happen before hitting this. """ secret = webhook.passthrough transaction_id = webhook.transaction_id payer_email = webhook.payer_email payer_id = webhook.payer_id subscr_id = webhook.subscr_id pennies = webhook.pennies months = webhook.months goldtype = webhook.goldtype buyer = webhook.buyer recipient = webhook.recipient signed = webhook.signed giftmessage = webhook.giftmessage comment = webhook.comment gold_recipient = recipient or buyer with gold_lock(gold_recipient): gold_recipient._sync_latest() days = days_from_months(months) if goldtype in ("onetime", "autorenew"): admintools.engolden(buyer, days) if goldtype == "onetime": subject = "thanks for buying reddit gold!" if g.lounge_reddit: message = strings.lounge_msg else: message = ":)" else: subject = "your reddit gold has been renewed!" message = "see the details of your subscription on " "[your userpage](/u/%s)" % buyer.name elif goldtype == "creddits": buyer._incr("gold_creddits", months) subject = "thanks for buying creddits!" message = "To spend them, visit http://%s/gold or your " "favorite person's userpage." % (g.domain) elif goldtype == "gift": send_gift(buyer, recipient, months, days, signed, giftmessage, comment) subject = "thanks for giving reddit gold!" message = "Your gift to %s has been delivered." % recipient.name status = "processed" secret_pieces = [goldtype] if goldtype == "gift": secret_pieces.append(recipient.name) secret_pieces.append(secret or "") secret = "-".join(secret_pieces) try: create_claimed_gold( transaction_id, payer_email, payer_id, pennies, days, secret, buyer._id, c.start_time, subscr_id=subscr_id, status=status, ) except IntegrityError: g.log.error("gold: got duplicate gold transaction") try: message = append_random_bottlecap_phrase(message) send_system_message(buyer, subject, message, distinguished="gold-auto") except MessageError: g.log.error("complete_gold_purchase: send_system_message error")
def complete_gold_purchase( secret, transaction_id, payer_email, payer_id, subscription_id, pennies, months, goldtype, buyer, recipient, signed, giftmessage, comment, ): """After receiving a message from a payment processor, apply gold. Shared endpoint for all payment processing systems. Validation of gold purchase (sender, recipient, etc.) should happen before hitting this. """ gold_recipient = recipient or buyer with gold_lock(gold_recipient): gold_recipient._sync_latest() days = days_from_months(months) if goldtype in ("onetime", "autorenew"): admintools.engolden(buyer, days) if goldtype == "onetime": subject = "thanks for buying reddit gold!" if g.lounge_reddit: lounge_url = "/space/" + g.lounge_reddit message = strings.lounge_msg % dict(link=lounge_url) else: message = ":)" else: subject = "your reddit gold has been renewed!" message = "see the details of your subscription on " "[your userpage](/u/%s)" % buyer.name elif goldtype == "creddits": buyer._incr("gold_creddits", months) subject = "thanks for buying creddits!" message = "To spend them, visit http://%s/gold or your favorite " "person's userpage." % (g.domain) elif goldtype == "gift": send_gift(buyer, recipient, months, days, signed, giftmessage, comment) subject = "thanks for giving reddit gold!" message = "Your gift to %s has been delivered." % recipient.name status = "processed" secret_pieces = [goldtype] if goldtype == "gift": secret_pieces.append(recipient.name) secret_pieces.append(secret) secret = "-".join(secret_pieces) try: create_claimed_gold( transaction_id, payer_email, payer_id, pennies, days, secret, buyer._id, c.start_time, subscr_id=subscription_id, status=status, ) except IntegrityError: g.log.error("gold: got duplicate gold transaction") try: send_system_message(buyer, subject, message) except MessageError: g.log.error("complete_gold_purchase: could not send system message")
def POST_spendcreddits(self, form, jquery, months, passthrough): if months is None or months < 1: form.set_html(".status", _("nice try.")) return days = months * 31 if not passthrough: raise ValueError("/spendcreddits got no passthrough?") blob_key, payment_blob = get_blob(passthrough) if payment_blob["goldtype"] not in ("gift", "code", "onetime"): raise ValueError("/spendcreddits payment_blob %s has goldtype %s" % (passthrough, payment_blob["goldtype"])) if payment_blob["account_id"] != c.user._id: fmt = ("/spendcreddits payment_blob %s has userid %d " + "but c.user._id is %d") raise ValueError(fmt % passthrough, payment_blob["account_id"], c.user._id) if payment_blob["goldtype"] == "gift": signed = payment_blob["signed"] giftmessage = _force_unicode(payment_blob["giftmessage"]) recipient_name = payment_blob["recipient"] try: recipient = Account._by_name(recipient_name) except NotFound: raise ValueError("Invalid username %s in spendcreddits, buyer = %s" % (recipient_name, c.user.name)) if recipient._deleted: form.set_html(".status", _("that user has deleted their account")) return redirect_to_spent = False thing = None with creddits_lock(c.user): if not c.user.employee and c.user.gold_creddits < months: msg = "%s is trying to sneak around the creddit check" msg %= c.user.name raise ValueError(msg) if payment_blob["goldtype"] == "gift": thing_fullname = payment_blob.get("thing") if not thing_fullname: thing_fullname = payment_blob.get("comment") thing = send_gift(c.user, recipient, months, days, signed, giftmessage, thing_fullname) form.set_html(".status", _("the gold has been delivered!")) elif payment_blob["goldtype"] == "code": try: send_gold_code(c.user, months, days) except MessageError: msg = _("there was an error creating a gift code. " "please try again later, or contact %(email)s " "for assistance.") % {'email': g.goldthanks_email} form.set_html(".status", msg) return form.set_html(".status", _("the gift code has been messaged to you!")) elif payment_blob["goldtype"] == "onetime": admintools.engolden(c.user, days) form.set_html(".status", _("the gold has been delivered!")) redirect_to_spent = True if not c.user.employee: c.user.gold_creddits -= months c.user._commit() form.find("button").hide() payment_blob["status"] = "processed" g.hardcache.set(blob_key, payment_blob, 86400 * 30) if thing: gilding_message = make_gold_message(thing, user_gilded=True) jquery.gild_thing(thing_fullname, gilding_message, thing.gildings) elif redirect_to_spent: form.redirect("/gold/thanks?v=spent-creddits")
def complete_gold_purchase(cls, webhook): """After receiving a message from a payment processor, apply gold. Shared endpoint for all payment processing systems. Validation of gold purchase (sender, recipient, etc.) should happen before hitting this. """ secret = webhook.passthrough transaction_id = webhook.transaction_id payer_email = webhook.payer_email payer_id = webhook.payer_id subscr_id = webhook.subscr_id pennies = webhook.pennies months = webhook.months goldtype = webhook.goldtype buyer = webhook.buyer recipient = webhook.recipient signed = webhook.signed giftmessage = webhook.giftmessage comment = webhook.comment gold_recipient = recipient or buyer with gold_lock(gold_recipient): gold_recipient._sync_latest() days = days_from_months(months) if goldtype in ('onetime', 'autorenew'): admintools.engolden(buyer, days) if goldtype == 'onetime': subject = "thanks for buying reddit gold!" if g.lounge_reddit: message = strings.lounge_msg else: message = ":)" else: subject = "your reddit gold has been renewed!" message = ("see the details of your subscription on " "[your userpage](/u/%s)" % buyer.name) elif goldtype == 'creddits': buyer._incr('gold_creddits', months) subject = "thanks for buying creddits!" message = ("To spend them, visit http://%s/gold or your " "favorite person's userpage." % (g.domain)) elif goldtype == 'gift': send_gift(buyer, recipient, months, days, signed, giftmessage, comment) subject = "thanks for giving reddit gold!" message = "Your gift to %s has been delivered." % recipient.name status = 'processed' secret_pieces = [goldtype] if goldtype == 'gift': secret_pieces.append(recipient.name) secret_pieces.append(secret or transaction_id) secret = '-'.join(secret_pieces) try: create_claimed_gold(transaction_id, payer_email, payer_id, pennies, days, secret, buyer._id, c.start_time, subscr_id=subscr_id, status=status) except IntegrityError: g.log.error('gold: got duplicate gold transaction') try: message = append_random_bottlecap_phrase(message) send_system_message(buyer, subject, message, distinguished='gold-auto') except MessageError: g.log.error( 'complete_gold_purchase: send_system_message error')
def finish(self, parameters, txn_id, payer_email, paying_id, subscr_id, custom, pennies, months, days): blob_key, payment_blob = get_blob(custom) buyer_id = payment_blob.get('account_id', None) if not buyer_id: dump_parameters(parameters) raise ValueError("No buyer_id in IPN with custom='%s'" % custom) try: buyer = Account._byID(buyer_id) except NotFound: dump_parameters(parameters) raise ValueError("Invalid buyer_id %d in IPN with custom='%s'" % (buyer_id, custom)) if subscr_id: buyer.gold_subscr_id = subscr_id instagift = False if payment_blob['goldtype'] in ('autorenew', 'onetime'): admintools.engolden(buyer, days) subject = _("Eureka! Thank you for investing in reddit gold!") message = _("Thank you for buying reddit gold. Your patronage " "supports the site and makes future development " "possible. For example, one month of reddit gold " "pays for 5 instance hours of reddit's servers.") message += "\n\n" + strings.gold_benefits_msg if g.lounge_reddit: message += "\n* " + strings.lounge_msg elif payment_blob['goldtype'] == 'creddits': buyer._incr("gold_creddits", months) buyer._commit() subject = _("Eureka! Thank you for investing in reddit gold " "creddits!") message = _("Thank you for buying creddits. Your patronage " "supports the site and makes future development " "possible. To spend your creddits and spread reddit " "gold, visit [/gold](/gold) or your favorite " "person's user page.") message += "\n\n" + strings.gold_benefits_msg + "\n\n" message += _("Thank you again for your support, and have fun " "spreading gold!") elif payment_blob['goldtype'] == 'gift': recipient_name = payment_blob.get('recipient', None) try: recipient = Account._by_name(recipient_name) except NotFound: dump_parameters(parameters) raise ValueError( "Invalid recipient_name %s in IPN/GC with custom='%s'" % (recipient_name, custom)) signed = payment_blob.get("signed", False) giftmessage = _force_unicode(payment_blob.get("giftmessage", "")) comment_id = payment_blob.get("comment") send_gift(buyer, recipient, months, days, signed, giftmessage, comment_id) instagift = True subject = _("Thanks for giving the gift of reddit gold!") message = _("Your classy gift to %s has been delivered.\n\n" "Thank you for gifting reddit gold. Your patronage " "supports the site and makes future development " "possible.") % recipient.name message += "\n\n" + strings.gold_benefits_msg + "\n\n" message += _("Thank you again for your support, and have fun " "spreading gold!") else: dump_parameters(parameters) raise ValueError("Got status '%s' in IPN/GC" % payment_blob['status']) # Reuse the old "secret" column as a place to record the goldtype # and "custom", just in case we need to debug it later or something secret = payment_blob['goldtype'] + "-" + custom if instagift: status = "instagift" else: status = "processed" create_claimed_gold(txn_id, payer_email, paying_id, pennies, days, secret, buyer_id, c.start_time, subscr_id, status=status) message = append_random_bottlecap_phrase(message) send_system_message(buyer, subject, message, distinguished='gold-auto') payment_blob["status"] = "processed" g.hardcache.set(blob_key, payment_blob, 86400 * 30)
def POST_ipn(self, paypal_secret, payment_status, txn_id, paying_id, payer_email, mc_currency, mc_gross, custom): parameters = request.POST.copy() # Make sure it's really PayPal if paypal_secret != g.PAYPAL_SECRET: log_text("invalid IPN secret", "%s guessed the wrong IPN secret" % request.ip, "warning") raise ValueError # Return early if it's an IPN class we don't care about response, psl = check_payment_status(payment_status) if response: return response # Return early if it's a txn_type we don't care about response, subscription = check_txn_type(parameters['txn_type'], psl) if subscription is None: subscr_id = None elif subscription == "new": subscr_id = parameters['subscr_id'] elif subscription == "cancel": cancel_subscription(parameters['subscr_id']) else: raise ValueError("Weird subscription: %r" % subscription) if response: return response # Check for the debug flag, and if so, dump the IPN dict if g.cache.get("ipn-debug"): g.cache.delete("ipn-debug") dump_parameters(parameters) if mc_currency != 'USD': raise ValueError("Somehow got non-USD IPN %r" % mc_currency) if not (txn_id and paying_id and payer_email and mc_gross): dump_parameters(parameters) raise ValueError("Got incomplete IPN") pennies = int(mc_gross * 100) months, days = months_and_days_from_pennies(pennies) # Special case: autorenewal payment existing = existing_subscription(subscr_id, paying_id, custom) if existing: if existing != "deleted account": create_claimed_gold ("P" + txn_id, payer_email, paying_id, pennies, days, None, existing._id, c.start_time, subscr_id) admintools.engolden(existing, days) g.log.info("Just applied IPN renewal for %s, %d days" % (existing.name, days)) return "Ok" # More sanity checks that all non-autorenewals should pass: if not custom: dump_parameters(parameters) raise ValueError("Got IPN with txn_id=%s and no custom" % txn_id) self.finish(parameters, "P" + txn_id, payer_email, paying_id, subscr_id, custom, pennies, months, days)
def finish(self, parameters, txn_id, payer_email, paying_id, subscr_id, custom, pennies, months, days): blob_key, payment_blob = get_blob(custom) buyer_id = payment_blob.get('account_id', None) if not buyer_id: dump_parameters(parameters) raise ValueError("No buyer_id in IPN with custom='%s'" % custom) try: buyer = Account._byID(buyer_id) except NotFound: dump_parameters(parameters) raise ValueError("Invalid buyer_id %d in IPN with custom='%s'" % (buyer_id, custom)) if subscr_id: buyer.gold_subscr_id = subscr_id instagift = False if payment_blob['goldtype'] in ('autorenew', 'onetime'): admintools.engolden(buyer, days) subject = _("Eureka! Thank you for investing in reddit gold!") message = _("Thank you for buying reddit gold. Your patronage " "supports the site and makes future development " "possible. For example, one month of reddit gold " "pays for 5 instance hours of reddit's servers.") message += "\n\n" + strings.gold_benefits_msg if g.lounge_reddit: message += "\n* " + strings.lounge_msg elif payment_blob['goldtype'] == 'creddits': buyer._incr("gold_creddits", months) buyer._commit() subject = _("Eureka! Thank you for investing in reddit gold " "creddits!") message = _("Thank you for buying creddits. Your patronage " "supports the site and makes future development " "possible. To spend your creddits and spread reddit " "gold, visit [/gold](/gold) or your favorite " "person's user page.") message += "\n\n" + strings.gold_benefits_msg + "\n\n" message += _("Thank you again for your support, and have fun " "spreading gold!") elif payment_blob['goldtype'] == 'gift': recipient_name = payment_blob.get('recipient', None) try: recipient = Account._by_name(recipient_name) except NotFound: dump_parameters(parameters) raise ValueError("Invalid recipient_name %s in IPN/GC with custom='%s'" % (recipient_name, custom)) signed = payment_blob.get("signed", False) giftmessage = _force_unicode(payment_blob.get("giftmessage", "")) comment_id = payment_blob.get("comment") send_gift(buyer, recipient, months, days, signed, giftmessage, comment_id) instagift = True subject = _("Thanks for giving the gift of reddit gold!") message = _("Your classy gift to %s has been delivered.\n\n" "Thank you for gifting reddit gold. Your patronage " "supports the site and makes future development " "possible.") % recipient.name message += "\n\n" + strings.gold_benefits_msg + "\n\n" message += _("Thank you again for your support, and have fun " "spreading gold!") else: dump_parameters(parameters) raise ValueError("Got status '%s' in IPN/GC" % payment_blob['status']) # Reuse the old "secret" column as a place to record the goldtype # and "custom", just in case we need to debug it later or something secret = payment_blob['goldtype'] + "-" + custom if instagift: status="instagift" else: status="processed" create_claimed_gold(txn_id, payer_email, paying_id, pennies, days, secret, buyer_id, c.start_time, subscr_id, status=status) message = append_random_bottlecap_phrase(message) send_system_message(buyer, subject, message, distinguished='gold-auto') payment_blob["status"] = "processed" g.hardcache.set(blob_key, payment_blob, 86400 * 30)