antiwork/gumroad · error · Purchase::PurchaseInvalid

Gifting is not yet enabled for pre-orders.

Error message

Gifting is not yet enabled for pre-orders.

What it means

The other branch of the same can_gift? failure: the seller has not disabled gifting, so product.can_gift? is false because is_in_preorder_state is true. Gifting is not implemented for pre-order products, and the message says so explicitly.

Source

Thrown at app/services/purchase/create_service.rb:341

    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."
      end
    end

    def validate_zip_code
      country_code_for_validation = purchase_params[:country].presence || purchase_params[:sales_tax_country_code_election]

      if purchase_params[:perceived_price_cents].to_i > 0 && country_code_for_validation == Compliance::Countries::USA.alpha2 && UsZipCodes.identify_state_code(purchase_params[:zip_code]).nil?
        Rails.logger.info("Zip code #{purchase_params[:zip_code]} is invalid, customer email #{purchase_params[:email]}")
        raise Purchase::PurchaseInvalid, "You entered a ZIP Code that doesn't exist within your country."
      end
    end

View on GitHub (pinned to afeacbd394)

Solutions

  1. Complete a regular pre-order without the gift option.
  2. Wait until the product is released, then gift it.
  3. Integrators: hide the gift toggle for products in pre-order state.
Defensive patterns

Strategy: validation

Validate before calling

params.delete(:gift) if params[:gift].present? && product.is_in_preorder_state?

Type guard

def gifting_available?(product)
  product.can_gift? # link.rb: !is_in_preorder_state && !user.gifting_disabled?
end

Try / catch

begin
  Purchase::CreateService.new(product:, params:, buyer:).perform
rescue Purchase::PurchaseInvalid => e
  params.delete(:gift) if e.message == 'Gifting is not yet enabled for pre-orders.'
end

Prevention

When it happens

Trigger: params[:gift] present, product.can_gift? false, product.user.gifting_disabled? false - which implies product.is_in_preorder_state is true.

Common situations: Buyer opens checkout while the product is a pre-order and selects gift; stale page after the seller converted the product to a pre-order.

Related errors


AI-assisted analysis of antiwork/gumroad@afeacbd394 (2026-08-21). Data as JSON: /api/errors/bf7f102e2118fab6. Report an issue: GitHub.