{"record":{"id":"e4782512a29eaeaa","repo":"antiwork/gumroad","slug":"error-message-preorder-errors-full-messages-0","errorCode":null,"errorMessage":"error_message (preorder.errors.full_messages[0])","messagePattern":"error_message \\(preorder\\.errors\\.full_messages\\[0\\]\\)","errorType":"exception","errorClass":"Purchase::PurchaseInvalid","httpStatus":null,"severity":"error","filePath":"app/services/purchase/create_service.rb","lineNumber":531,"sourceCode":"    end\n\n    def giftee_email\n      giftee_purchaser&.email || gift_params[:giftee_email]\n    end\n\n    def build_preorder(locked_rate: nil)\n      raise Purchase::PurchaseInvalid, \"The product was just released. Refresh the page to purchase it.\" unless product.is_in_preorder_state?\n\n      self.preorder = product.preorder_link.build_preorder(purchase)\n      if purchase.is_part_of_combined_charge?\n        purchase.prepare_for_charge!(locked_rate:)\n      else\n        preorder.authorize!(locked_rate:)\n        error_message = preorder.errors.full_messages[0]\n        if purchase.is_test_purchase?\n          preorder.mark_test_authorization_successful!\n        elsif error_message.present?\n          raise Purchase::PurchaseInvalid, error_message\n        elsif purchase.requires_sca?\n          # Leave the preorder in `in_progress` state until the the required UI action is completed.\n          # Check back later to see if it has been completed. If not, transition to a failed state.\n          FailAbandonedPurchaseWorker.perform_in(ChargeProcessor::TIME_TO_COMPLETE_SCA, purchase.id)\n        else\n          preorder.mark_authorization_successful!\n        end\n      end\n    end\n\n    def set_purchaser_for(purchase, purchase_email)\n      if buyer.present?\n        purchase.purchaser = buyer unless purchase.is_gift_receiver_purchase\n      else\n        user_from_email = User.find_by(email: purchase_email)\n        # This limits test purchase to be done in logged out mode\n        if purchase.link.user != user_from_email\n          purchase.purchaser = user_from_email","sourceCodeStart":513,"sourceCodeEnd":549,"githubUrl":"https://github.com/antiwork/gumroad/blob/afeacbd394069a1cbf0c6c50ee8e900925050370/app/services/purchase/create_service.rb#L513-L549","documentation":"For a standalone pre-order (not part of a combined charge), preorder.authorize! reserves the charge; when it returns with errors and the purchase is not a test purchase, the first error message is re-raised as PurchaseInvalid. The text comes from Preorder validations - most often payment-authorization failures from the charge processor. SCA-required purchases take a different branch (scheduled FailAbandonedPurchaseWorker) instead of raising.","triggerScenarios":"preorder.authorize!(locked_rate:) populates preorder.errors; purchase.is_test_purchase? is false; purchase.requires_sca? is false - so the error branch fires and preorder.errors.full_messages[0] is raised verbatim.","commonSituations":"Card declined at pre-order authorization; charge-processor errors (amount, currency, processing limits); authorizing against a payment method that cannot be reserved.","solutions":["Read the raised message - it surfaces the underlying authorization failure reason from the preorder/charge processor.","Retry with a valid payment method after the failure is addressed.","Integrators: log preorder.errors.full_messages (all entries) when this raise fires to capture the complete processor response."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"begin\n  purchase, error = Purchase::CreateService.new(product:, params:, buyer:).perform\nrescue Purchase::PurchaseInvalid => e\n  # authorization failed: message carries the processor reason; prompt for a new payment method\n  Rails.logger.warn(\"preorder authorization failed: #{e.message}\")\n  render_checkout_error(e.message)\nend","preventionTips":["Validate the payment method (not expired, authorizable) before starting pre-order checkout.","Log preorder.errors.full_messages when this raise fires - the raised string is only the first error.","Distinguish this from the SCA branch: SCA-needed authorizations do not raise, they schedule a later completion check."],"tags":["preorder","payment-authorization","passthrough","checkout","gumroad"],"backgroundTag":"preorder-authorization-failed","analyzedSha":"afeacbd394069a1cbf0c6c50ee8e900925050370","analyzedAt":"2026-08-21T17:58:52.159Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}