<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Freelance Deal Desk</title>
    <description>The latest articles on DEV Community by Freelance Deal Desk (@freelancedealdesk).</description>
    <link>https://dev.to/freelancedealdesk</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4054189%2Fe41f2ca3-4445-4b54-8c87-4e7c466812a1.png</url>
      <title>DEV Community: Freelance Deal Desk</title>
      <link>https://dev.to/freelancedealdesk</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/freelancedealdesk"/>
    <language>en</language>
    <item>
      <title>Cómo calcular el precio de un proyecto freelance sin improvisar</title>
      <dc:creator>Freelance Deal Desk</dc:creator>
      <pubDate>Thu, 30 Jul 2026 16:26:57 +0000</pubDate>
      <link>https://dev.to/freelancedealdesk/como-calcular-el-precio-de-un-proyecto-freelance-sin-improvisar-2el</link>
      <guid>https://dev.to/freelancedealdesk/como-calcular-el-precio-de-un-proyecto-freelance-sin-improvisar-2el</guid>
      <description>&lt;p&gt;Cotizar un proyecto freelance no consiste en multiplicar horas por tarifa. Ese cálculo es un punto de partida, pero deja fuera el tiempo no facturable, el riesgo, los cambios de alcance y las comisiones.&lt;/p&gt;

&lt;p&gt;Una propuesta profesional necesita mostrar una cifra que puedas defender y un alcance que el cliente entienda.&lt;/p&gt;

&lt;h2&gt;
  
  
  La fórmula mínima
&lt;/h2&gt;

&lt;p&gt;Empieza por convertir tu objetivo mensual en una tarifa operativa:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;tarifa operativa = objetivo mensual / horas facturables reales&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Las horas facturables no son las horas que trabajas. Son las que realmente puedes dedicar al cliente después de ventas, reuniones, administración, aprendizaje y descanso. Si trabajas 160 horas al mes pero sólo 80 son facturables, usar 160 para cotizar reduce tu tarifa a la mitad.&lt;/p&gt;

&lt;p&gt;Después calcula el costo base:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;costo base = tarifa operativa × horas estimadas&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Y protege ese resultado:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;precio recomendado = (costo base + contingencia) / (1 − margen)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;La contingencia cubre incertidumbre técnica razonable. El margen cubre la responsabilidad, la comunicación y el valor de entregar un resultado que funciona. No es un número inflado: es la parte que hace sostenible el trabajo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Un ejemplo sencillo
&lt;/h2&gt;

&lt;p&gt;Supón un objetivo mensual de $3,000 USD y 80 horas facturables. Tu tarifa operativa es $37.50/hora. Para una estimación de 18 horas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Costo base: $675&lt;/li&gt;
&lt;li&gt;Contingencia del 10%: $67.50&lt;/li&gt;
&lt;li&gt;Con margen del 35%: $1,142.31&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;El resultado no obliga a cobrar exactamente esa cantidad. Sirve para decidir con claridad si el proyecto debe tener un precio fijo, dividirse en fases o requerir una conversación de alcance antes de dar un número final.&lt;/p&gt;

&lt;h2&gt;
  
  
  Antes de enviar una cifra, responde esto
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;¿Qué resultado concreto espera el cliente?&lt;/li&gt;
&lt;li&gt;¿Qué queda fuera del trabajo?&lt;/li&gt;
&lt;li&gt;¿Qué necesita entregar el cliente para empezar?&lt;/li&gt;
&lt;li&gt;¿Cuántas rondas de revisión están incluidas?&lt;/li&gt;
&lt;li&gt;¿Qué evento convierte el proyecto en “terminado”?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Si una respuesta no está clara, anótala como supuesto en la propuesta. Así un cambio deja de ser una discusión ambigua y pasa a ser una decisión comercial explícita.&lt;/p&gt;

&lt;h2&gt;
  
  
  La cotización es una herramienta de ventas
&lt;/h2&gt;

&lt;p&gt;Una propuesta que sólo muestra un precio fuerza al cliente a adivinar el resto. Una buena propuesta conecta contexto, solución, entregables, calendario, inversión y próximos pasos. Eso reduce fricción y te permite decir “sí, con este alcance” en vez de negociar desde el miedo.&lt;/p&gt;

&lt;p&gt;Preparé un kit comercial editable para freelancers de software con cuestionario de descubrimiento, plantilla de propuesta, calculadora de proyectos en Excel y mensajes de seguimiento. Está disponible en &lt;a href="https://freelance-deal-desk-kit-mx.claudioarreguin20.chatgpt.site" rel="noopener noreferrer"&gt;Freelance Deal Desk&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>freelance</category>
      <category>career</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Stripe webhooks need a state machine, not just a switch statement</title>
      <dc:creator>Freelance Deal Desk</dc:creator>
      <pubDate>Thu, 30 Jul 2026 05:38:05 +0000</pubDate>
      <link>https://dev.to/freelancedealdesk/stripe-webhooks-need-a-state-machine-not-just-a-switch-statement-49el</link>
      <guid>https://dev.to/freelancedealdesk/stripe-webhooks-need-a-state-machine-not-just-a-switch-statement-49el</guid>
      <description>&lt;p&gt;Most Stripe Checkout examples stop at this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;switch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;payment_intent.succeeded&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;// mark paid&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is a useful beginning, but it is not yet a payment workflow. A real booking flow also has a calendar slot, a database record, retries, late events, and sometimes a human approval step. Treating each webhook as an isolated callback leaves gaps where a paid customer can lose a slot—or where a failed payment leaves a slot unavailable forever.&lt;/p&gt;

&lt;p&gt;Here is the smaller model I use before wiring an application to live vendor APIs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Make the booking state explicit
&lt;/h2&gt;

&lt;p&gt;Record three separate facts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;payment_status&lt;/code&gt;: &lt;code&gt;awaiting_payment&lt;/code&gt;, &lt;code&gt;paid&lt;/code&gt;, or &lt;code&gt;failed&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;slot_status&lt;/code&gt;: &lt;code&gt;held&lt;/code&gt;, &lt;code&gt;confirmed&lt;/code&gt;, or &lt;code&gt;released&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;approval_status&lt;/code&gt;: &lt;code&gt;not_required&lt;/code&gt;, &lt;code&gt;pending_approval&lt;/code&gt;, &lt;code&gt;approved&lt;/code&gt;, &lt;code&gt;denied&lt;/code&gt;, &lt;code&gt;countered&lt;/code&gt;, or &lt;code&gt;expired&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those states are deliberately independent. A booking can be paid while its calendar confirmation is retrying. A low-value booking can be held while an operator decides whether to accept it. And a failure must release a held slot without touching a slot that has already been confirmed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Idempotency belongs at the event boundary
&lt;/h2&gt;

&lt;p&gt;Stripe retries webhooks. Your endpoint must therefore persist the event ID before it performs side effects. A second delivery should return success without charging, confirming, or releasing anything again.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;seenStripeEvents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;duplicate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="nx"&gt;seenStripeEvents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;payment_intent.succeeded&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;confirmSlot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;booking&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;calSlotId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;booking&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slotKey&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;writeBilledBooking&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;booking&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In production, &lt;code&gt;seenStripeEvents&lt;/code&gt; should be a table with a unique event ID, written in the same transaction that changes the booking state. An in-memory set only makes the example easy to read.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use one stable key for calendar side effects
&lt;/h2&gt;

&lt;p&gt;A booking ID makes a good idempotency key for the calendar provider:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;booking:&amp;lt;booking-id&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pass that same key when holding, confirming, and releasing a slot. If a network request times out after the provider completed its work, retrying with the same key is safe. This is much better than trying to infer state from a transient API error.&lt;/p&gt;

&lt;h2&gt;
  
  
  Never trust a webhook without its raw-body signature check
&lt;/h2&gt;

&lt;p&gt;The signature must be computed over the exact raw request body and rejected outside a short replay window. Do this before JSON parsing when the framework requires it. Constant-time comparison also avoids turning a signature endpoint into an oracle.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;expected&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createHmac&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sha256&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;rawBody&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;digest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hex&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;valid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;actual&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;expected&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
  &lt;span class="nf"&gt;timingSafeEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;actual&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hex&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;expected&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hex&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Test the recovery paths first
&lt;/h2&gt;

&lt;p&gt;The happy path is easy to picture. The useful tests are the awkward ones:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;payment_intent.succeeded&lt;/code&gt; delivered twice confirms the slot once.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;payment_intent.payment_failed&lt;/code&gt; releases a held slot.&lt;/li&gt;
&lt;li&gt;A manual denial releases its hold.&lt;/li&gt;
&lt;li&gt;An expired approval releases its hold.&lt;/li&gt;
&lt;li&gt;A successful payment cannot bypass a required approval.&lt;/li&gt;
&lt;li&gt;Altered or stale webhook signatures are rejected.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Writing these tests before connecting Stripe or a calendar API forces the product decision into code: every hold has a release path, every external event is repeat-safe, and billed records have an immutable payment ID.&lt;/p&gt;

&lt;p&gt;For a separate walkthrough of promotion codes in Stripe Checkout, see &lt;a href="https://dev.to/freelancedealdesk/stripe-checkout-promotion-codes-a-safe-test-first-rollout-2405"&gt;this test-first guide&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>api</category>
      <category>architecture</category>
      <category>backend</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>Stripe Checkout promotion codes: a safe test-first rollout</title>
      <dc:creator>Freelance Deal Desk</dc:creator>
      <pubDate>Thu, 30 Jul 2026 05:23:28 +0000</pubDate>
      <link>https://dev.to/freelancedealdesk/stripe-checkout-promotion-codes-a-safe-test-first-rollout-2405</link>
      <guid>https://dev.to/freelancedealdesk/stripe-checkout-promotion-codes-a-safe-test-first-rollout-2405</guid>
      <description>&lt;p&gt;Stripe-hosted Checkout is designed to keep payment flows simple, but promotions deserve the same care as any other billing change. The safest rollout is small, reversible, and tested before it touches a live subscription.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Identify the Checkout path first
&lt;/h2&gt;

&lt;p&gt;Start by confirming whether the hosted page is created through the Checkout Sessions API or a Payment Link. The two paths expose promotion settings differently, so this one question prevents needless changes to an otherwise working integration.&lt;/p&gt;

&lt;p&gt;For a Checkout Session created on your server, enable the customer-facing field with &lt;code&gt;allow_promotion_codes: true&lt;/code&gt;. For Payment Links, Stripe supports promotion codes in the Dashboard and through its Payment Links settings.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Separate the discount from the public code
&lt;/h2&gt;

&lt;p&gt;A coupon defines the discount. A promotion code is the customer-facing code that can apply that discount. Give the promotion code a clear scope and an expiration or redemption limit when appropriate. That makes it easier to stop a campaign without rewriting your Checkout flow.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Test with separate test-mode objects
&lt;/h2&gt;

&lt;p&gt;Use a test-mode product and price. Run a full checkout using the proposed promotion code, then confirm:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the discounted total is correct;&lt;/li&gt;
&lt;li&gt;subscription behavior is still correct;&lt;/li&gt;
&lt;li&gt;success and cancel URLs are unchanged;&lt;/li&gt;
&lt;li&gt;your existing post-checkout handling still runs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For many integrations, enabling a promotion field is a focused configuration change—not a reason to rework prices, webhooks, or billing logic.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Keep a rollback switch
&lt;/h2&gt;

&lt;p&gt;Before production, decide who can disable the promotion code and where that is documented. A promotion should be easy to retire. Record the code, the linked coupon, its scope, and the test performed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Production-ready implementation template
&lt;/h2&gt;

&lt;p&gt;If you want a starting point that includes the Checkout creation route, customer-entered promotion codes, signed webhooks, idempotent fulfillment, and a test checklist, I made a production kit for exactly this workflow.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://payhip.com/b/6JAjV" rel="noopener noreferrer"&gt;Stripe Checkout Promotion Codes — Production Kit (USD 29)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Launch note: use code &lt;code&gt;LAUNCH10&lt;/code&gt; at checkout for 10% off this kit.&lt;/p&gt;

&lt;p&gt;This article is educational and is not financial, tax, or legal advice. Always test in Stripe Test mode before changing a live payment flow.&lt;/p&gt;

</description>
      <category>stripe</category>
      <category>webdev</category>
      <category>typescript</category>
    </item>
    <item>
      <title>5 preguntas antes de cotizar un proyecto de software</title>
      <dc:creator>Freelance Deal Desk</dc:creator>
      <pubDate>Thu, 30 Jul 2026 04:20:21 +0000</pubDate>
      <link>https://dev.to/freelancedealdesk/5-preguntas-antes-de-cotizar-un-proyecto-de-software-i62</link>
      <guid>https://dev.to/freelancedealdesk/5-preguntas-antes-de-cotizar-un-proyecto-de-software-i62</guid>
      <description>&lt;p&gt;Una consulta que dice “¿cuánto cobras por hacer una web?” no es todavía un proyecto. Es una señal de que alguien tiene una necesidad, pero aún no ha convertido esa necesidad en alcance, prioridad ni inversión.&lt;/p&gt;

&lt;p&gt;Responder con un número demasiado pronto suele crear uno de dos problemas: cobras por una versión imaginaria del trabajo, o pasas días persiguiendo detalles que debieron estar claros al principio.&lt;/p&gt;

&lt;p&gt;Estas son las cinco preguntas que uso para convertir una conversación inicial en una propuesta que se pueda evaluar.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. ¿Qué debería ser diferente cuando esto esté terminado?
&lt;/h2&gt;

&lt;p&gt;No preguntes solamente qué páginas o funcionalidades quieren. Pregunta qué cambio esperan conseguir: más solicitudes, menos trabajo manual, una mejor demostración del producto, una experiencia de compra más simple.&lt;/p&gt;

&lt;p&gt;La respuesta revela el resultado que realmente valoran. También te ayuda a distinguir entre una petición urgente y una mejora “algún día”.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. ¿Qué está ocurriendo ahora y por qué no funciona?
&lt;/h2&gt;

&lt;p&gt;Una solución tiene sentido sólo dentro de su contexto. Pide un ejemplo concreto del flujo actual: quién hace qué, qué tarda demasiado, dónde se pierden oportunidades y qué ya intentaron.&lt;/p&gt;

&lt;p&gt;Esta pregunta reduce el riesgo de construir una función bonita que no resuelve el cuello de botella real.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. ¿Quién decide y quién usará el resultado cada día?
&lt;/h2&gt;

&lt;p&gt;El comprador, la persona que aprueba y el usuario final a menudo no son la misma persona. Saberlo cambia cómo presentas la propuesta, qué validaciones necesitas y cuánto tiempo debes reservar para revisiones.&lt;/p&gt;

&lt;p&gt;Una frase útil es: “Además de nosotros dos, ¿quién necesita estar de acuerdo antes de empezar?”.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. ¿Qué tiene que incluir esta primera versión y qué puede esperar?
&lt;/h2&gt;

&lt;p&gt;Pide que separen el “imprescindible para lanzar” de las mejoras deseables. Después confirma por escrito la primera lista.&lt;/p&gt;

&lt;p&gt;No se trata de recortar valor: se trata de proteger la fecha, el presupuesto y la calidad. Un alcance pequeño y claro es mucho más convincente que una lista interminable de posibilidades.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. ¿Qué fecha, presupuesto o restricción no podemos ignorar?
&lt;/h2&gt;

&lt;p&gt;La fecha puede venir de una campaña, un evento, una renovación o una operación interna. El presupuesto puede tener margen, pero rara vez es infinito. Preguntar de forma directa permite proponer alternativas reales: una fase inicial, menos integraciones o un calendario distinto.&lt;/p&gt;

&lt;p&gt;Evitar la conversación de presupuesto no la elimina; sólo la deja para el peor momento.&lt;/p&gt;

&lt;h2&gt;
  
  
  Convierte las respuestas en una propuesta de una página
&lt;/h2&gt;

&lt;p&gt;Después de la llamada, resume lo escuchado en este orden:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;El problema y el resultado esperado.&lt;/li&gt;
&lt;li&gt;El alcance de la primera versión.&lt;/li&gt;
&lt;li&gt;Qué no está incluido todavía.&lt;/li&gt;
&lt;li&gt;La inversión, calendario y forma de trabajo.&lt;/li&gt;
&lt;li&gt;El siguiente paso concreto para empezar.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Cuando el cliente puede reconocer su propia situación en las primeras líneas de una propuesta, la conversación deja de ser una comparación de precios y se convierte en una decisión de negocio.&lt;/p&gt;




&lt;p&gt;Durante los próximos 7 días, obtén &lt;strong&gt;&lt;a href="https://freelance-deal-desk-kit-mx.claudioarreguin20.chatgpt.site" rel="noopener noreferrer"&gt;Freelance Deal Desk&lt;/a&gt;&lt;/strong&gt; por &lt;strong&gt;$20 USD&lt;/strong&gt; con el código &lt;strong&gt;START20&lt;/strong&gt;. Incluye cuestionario de descubrimiento, plantilla de propuesta, calculadora de proyectos y mensajes de seguimiento para freelancers que quieren vender con más claridad.&lt;/p&gt;

</description>
      <category>productivity</category>
    </item>
  </channel>
</rss>
