{"record":{"id":"dc52e575df902291","repo":"antiwork/gumroad","slug":"invalid-free-trial-information-provided-please-tr","errorCode":null,"errorMessage":"Invalid free trial information provided. Please try again.","messagePattern":"Invalid free trial information provided\\. Please try again\\.","errorType":"exception","errorClass":"Purchase::PurchaseInvalid","httpStatus":null,"severity":"error","filePath":"app/services/purchase/create_service.rb","lineNumber":376,"sourceCode":"    end\n\n    def perceived_price_matches_accepted_offer?(offer_code)\n      return false unless offer_code\n\n      original_offer_code = purchase.offer_code\n      purchase.offer_code = offer_code\n      purchase.minimum_paid_price_cents + params[:tip_cents].to_i == purchase_params[:perceived_price_cents].to_i\n    ensure\n      purchase.offer_code = original_offer_code if purchase\n    end\n\n    def validate_perceived_free_trial_params\n      return if is_gift?\n\n      free_trial_params = params[:perceived_free_trial_duration]\n      if product.free_trial_enabled?\n        if !free_trial_params.present? || !free_trial_params[:amount].present? || !free_trial_params[:unit].present?\n          raise Purchase::PurchaseInvalid, \"Invalid free trial information provided. Please try again.\"\n        elsif free_trial_params[:amount].to_i != product.free_trial_duration_amount || free_trial_params[:unit] != product.free_trial_duration_unit\n          raise Purchase::PurchaseInvalid, \"The product's free trial has changed, please refresh the page!\"\n        end\n      elsif free_trial_params.present?\n        raise Purchase::PurchaseInvalid, \"Invalid free trial information provided. Please try again.\"\n      end\n    end\n\n    def validate_bundle_products\n      return unless product.is_bundle?\n\n      product.bundle_products.alive.each do |bundle_product|\n        if params[:bundle_products].none? { _1[:product_id] == bundle_product.product.external_id && _1[:variant_id] == bundle_product.variant&.external_id && _1[:quantity].to_i == bundle_product.quantity }\n          raise Purchase::PurchaseInvalid, \"The bundle's contents have changed. Please refresh the page!\"\n        end\n\n        validate_bundle_component_inventory(bundle_product)\n      end","sourceCodeStart":358,"sourceCodeEnd":394,"githubUrl":"https://github.com/antiwork/gumroad/blob/afeacbd394069a1cbf0c6c50ee8e900925050370/app/services/purchase/create_service.rb#L358-L394","documentation":"For a product with free_trial_enabled?, the checkout must echo the trial terms back: params[:perceived_free_trial_duration] must carry both :amount and :unit. Missing or incomplete params raise 'Invalid free trial information provided' so a trial purchase cannot be created from ambiguous terms. Gift purchases skip this validation entirely.","triggerScenarios":"product.free_trial_enabled? true, not a gift, and params[:perceived_free_trial_duration] is nil, or its :amount or :unit key is missing/blank.","commonSituations":"Checkout page loaded before the seller enabled the trial (stale state); API integrations that omit the trial echo fields; client sending only one of the two fields.","solutions":["Refresh the checkout page to pick up the product's current trial terms.","Integrators: always send perceived_free_trial_duration: { amount:, unit: } mirroring the product's free_trial_duration_amount/unit.","Re-fetch product state immediately before submit and reconcile the params."],"exampleFix":"# before: trial terms not echoed\nparams[:perceived_free_trial_duration] = nil # product.free_trial_enabled?\n\n# after: echo the product's current terms\nparams[:perceived_free_trial_duration] = { amount: product.free_trial_duration_amount, unit: product.free_trial_duration_unit }","handlingStrategy":"validation","validationCode":"if product.free_trial_enabled? && params[:gift].blank?\n  trial = params[:perceived_free_trial_duration]\n  params[:perceived_free_trial_duration] = { amount: product.free_trial_duration_amount, unit: product.free_trial_duration_unit } if trial.blank? || trial[:amount].blank? || trial[:unit].blank?\nend","typeGuard":"def complete_trial_params?(trial_params)\n  trial_params.present? && trial_params[:amount].present? && trial_params[:unit].present?\nend","tryCatchPattern":"begin\n  Purchase::CreateService.new(product:, params:, buyer:).perform\nrescue Purchase::PurchaseInvalid => e\n  # refresh flow: re-fetch product and rebuild trial params, then let the buyer resubmit\n  redirect_to_checkout if e.message == 'Invalid free trial information provided. Please try again.'\nend","preventionTips":["Always echo the product's current free_trial_duration_amount and unit on trial-enabled products.","Send trial params as a complete { amount:, unit: } hash - partial hashes fail."],"tags":["free-trial","params","stale-state","checkout","gumroad"],"backgroundTag":"free-trial-param-mismatch","analyzedSha":"afeacbd394069a1cbf0c6c50ee8e900925050370","analyzedAt":"2026-08-21T17:58:52.159Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}