antiwork/gumroad · error · Purchase::PurchaseInvalid
You can't gift your own product. To give it away for free, c
Error message
You can't gift your own product. To give it away for free, create a 100% off discount code under Checkout > Discounts and share the checkout link.
What it means
create_gift rejects a gift when buyer == product.user: a seller buying their own product can only ever be a test purchase, and test purchases were never built for gifts. The message names the supported alternative (a 100% off discount code) because the old internal-capability wording generated support tickets asking Gumroad to 'enable' test gifts.
Source
Thrown at app/services/purchase/create_service.rb:329
return nil, nil, result.slice(:success, :requires_card_action, :client_secret, :purchase)
end
purchase = result[:purchase] || restartable_subscription.original_purchase
self.purchase = purchase
Rails.logger.info("Subscription #{restartable_subscription.external_id} restarted during checkout for product #{product.id}")
return purchase, nil
else
return nil, result[:error_message]
end
end
def create_gift
# A seller buying their own product can only ever be a test purchase, and test purchases were
# never built for gifts, so this case has to be rejected. The message names what the seller
# actually did and points at the supported way to give a product away, because the old wording
# ("Test gift purchases have not been enabled yet.") described an internal capability and read
# as a flag we could switch on for them, which generated support tickets asking us to do that.
raise Purchase::PurchaseInvalid, "You can't gift your own product. To give it away for free, create a 100% off discount code under Checkout > Discounts and share the checkout link." if buyer == product.user
raise Purchase::PurchaseInvalid, "You cannot gift a product to yourself. Please try gifting to another email." if giftee_email == purchase_params[:email]
raise Purchase::PurchaseInvalid, "Gift purchases cannot be on installment plans." if params[:pay_in_installments]
if product.can_gift?
gift = product.gifts.build(giftee_email:, gift_note: gift_params[:gift_note], gifter_email: params[:purchase][:email], is_recipient_hidden: gift_params[:giftee_email].blank?)
error_message = gift.save ? nil : gift.errors.full_messages[0]
raise Purchase::PurchaseInvalid, error_message if error_message.present?
gift
else
error_message = product.user.gifting_disabled? ? "The creator has disabled gifting for their products." : "Gifting is not yet enabled for pre-orders."
raise Purchase::PurchaseInvalid, error_message
end
end
def validate_perceived_price
if purchase_params[:perceived_price_cents] && !Purchase::MAX_PRICE_RANGE.cover?(purchase_params[:perceived_price_cents])
raise Purchase::PurchaseInvalid, "Purchase price is invalid. Please check the price."View on GitHub (pinned to afeacbd394)
Solutions
- Create a 100% off discount code under Checkout > Discounts and share its checkout link with the recipient.
- To exercise the gift flow end-to-end, purchase from a different, non-seller account.
- Drop params[:gift] when making a seller test purchase.
Example fix
# before: seller account submits a gift purchase of its own product
params[:gift] = { giftee_email: 'friend@example.com' } # buyer == product.user
# after: self-purchases are test purchases; give the product away via a 100% off code instead
params.delete(:gift) Defensive patterns
Strategy: validation
Validate before calling
params.delete(:gift) if params[:gift].present? && buyer == product.user
Type guard
def self_gift?(buyer, product, gift_params) gift_params.present? && buyer == product.user end
Try / catch
begin
Purchase::CreateService.new(product:, params:, buyer:).perform
rescue Purchase::PurchaseInvalid => e
# message already contains the actionable guidance (100% off code); show it verbatim
render_checkout_error(e.message) if e.message.start_with?("You can't gift your own product")
end Prevention
- Hide the gift option when the current user is the product's seller.
- Use 100% off discount codes for giveaways instead of attempting self-gifts.
- Run gift end-to-end tests from a non-seller account.
When it happens
Trigger: The authenticated buyer equals product.user and gift params are present (params[:gift] set, so is_gift? is true) when Purchase::CreateService#perform runs.
Common situations: Sellers testing the gift flow on their own product; creators trying to send their own product to a customer as a gift.
Related errors
- You cannot gift a product to yourself. Please try gifting to
- Gift purchases cannot be on installment plans.
- The creator has disabled gifting for their products.
- Gifting is not yet enabled for pre-orders.
- giftee_purchase.errors.full_messages[0]
AI-assisted analysis of antiwork/gumroad@afeacbd394 (2026-08-21).
Data as JSON: /api/errors/8d08558e6dd8f370.
Report an issue: GitHub.