<mxfile host="app.diagrams.net" agent="ApiPay Hub docs-portal" type="device" version="24.7.17">
  <diagram id="apipay-checkout-alojado" name="Checkout alojado (boton de pago)">
    <mxGraphModel dx="1800" dy="1600" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1169" pageHeight="826" math="0" shadow="0">
      <root>
        <mxCell id="0" />
        <mxCell id="1" parent="0" />

        <mxCell id="ll-ec" value="Comercio&lt;br&gt;backend sk_test_ y tienda" style="shape=umlLifeline;perimeter=lifelinePerimeter;whiteSpace=wrap;html=1;container=0;collapsible=0;recursiveResize=0;outlineConnect=0;size=50;fillColor=#FFF8E1;strokeColor=#F9A825;fontColor=#1A1A1A;fontSize=11" vertex="1" parent="1">
          <mxGeometry x="40" y="40" width="170" height="1100" as="geometry" />
        </mxCell>
        <mxCell id="ll-br" value="Navegador&lt;br&gt;del comprador" style="shape=umlLifeline;perimeter=lifelinePerimeter;whiteSpace=wrap;html=1;container=0;collapsible=0;recursiveResize=0;outlineConnect=0;size=50;fillColor=#FFF8E1;strokeColor=#F9A825;fontColor=#1A1A1A;fontSize=11" vertex="1" parent="1">
          <mxGeometry x="240" y="40" width="170" height="1100" as="geometry" />
        </mxCell>
        <mxCell id="ll-co" value="Checkout alojado&lt;br&gt;(checkout-widget, modo pagina)" style="shape=umlLifeline;perimeter=lifelinePerimeter;whiteSpace=wrap;html=1;container=0;collapsible=0;recursiveResize=0;outlineConnect=0;size=50;fillColor=#E0F7FA;strokeColor=#00838F;fontColor=#1A1A1A;fontSize=11" vertex="1" parent="1">
          <mxGeometry x="440" y="40" width="170" height="1100" as="geometry" />
        </mxCell>
        <mxCell id="ll-pa" value="payment-api" style="shape=umlLifeline;perimeter=lifelinePerimeter;whiteSpace=wrap;html=1;container=0;collapsible=0;recursiveResize=0;outlineConnect=0;size=50;fillColor=#E3F2FD;strokeColor=#1565C0;fontColor=#1A1A1A;fontSize=11" vertex="1" parent="1">
          <mxGeometry x="640" y="40" width="170" height="1100" as="geometry" />
        </mxCell>
        <mxCell id="ll-pg" value="Pasarela que&lt;br&gt;elige el comprador" style="shape=umlLifeline;perimeter=lifelinePerimeter;whiteSpace=wrap;html=1;container=0;collapsible=0;recursiveResize=0;outlineConnect=0;size=50;fillColor=#F3E5F5;strokeColor=#6A1B9A;fontColor=#1A1A1A;fontSize=11" vertex="1" parent="1">
          <mxGeometry x="840" y="40" width="170" height="1100" as="geometry" />
        </mxCell>

        <mxCell id="m01" value="1. POST /v1/payment-intents SIN gateway_id - sk_test_, Idempotency-Key, return_url, merchant_return_url" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;verticalAlign=bottom;labelBackgroundColor=#FFFFFF;strokeColor=#1565C0;fontColor=#0D47A1;fontSize=10;fontStyle=1;endArrow=block;endFill=1;exitX=1;exitY=0.075;exitDx=0;exitDy=0;entryX=0;entryY=0.075;entryDx=0;entryDy=0" edge="1" parent="1" source="ll-ec" target="ll-pa">
          <mxGeometry relative="1" as="geometry" />
        </mxCell>
        <mxCell id="m02" value="2. 201 con pi_..., client_secret y checkout_url" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;verticalAlign=bottom;labelBackgroundColor=#FFFFFF;strokeColor=#1565C0;fontColor=#0D47A1;fontSize=10;fontStyle=1;dashed=1;endArrow=open;endFill=0;endSize=10;exitX=0;exitY=0.12;exitDx=0;exitDy=0;entryX=1;entryY=0.12;entryDx=0;entryDy=0" edge="1" parent="1" source="ll-pa" target="ll-ec">
          <mxGeometry relative="1" as="geometry" />
        </mxCell>
        <mxCell id="m03" value="3. manda al comprador a checkout_url" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;verticalAlign=bottom;labelBackgroundColor=#FFFFFF;strokeColor=#455A64;fontColor=#1A1A1A;fontSize=10;dashed=1;endArrow=open;endFill=0;endSize=10;exitX=1;exitY=0.165;exitDx=0;exitDy=0;entryX=0;entryY=0.165;entryDx=0;entryDy=0" edge="1" parent="1" source="ll-ec" target="ll-br">
          <mxGeometry relative="1" as="geometry" />
        </mxCell>
        <mxCell id="m04" value="4. GET /session?pk=pk_test_...#client_secret=pi_..._secret_... - el secreto va en el FRAGMENTO" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;verticalAlign=bottom;labelBackgroundColor=#FFFFFF;strokeColor=#455A64;fontColor=#1A1A1A;fontSize=10;endArrow=block;endFill=1;exitX=1;exitY=0.21;exitDx=0;exitDy=0;entryX=0;entryY=0.21;entryDx=0;entryDy=0" edge="1" parent="1" source="ll-br" target="ll-co">
          <mxGeometry relative="1" as="geometry" />
        </mxCell>
        <mxCell id="m05" value="5. GET /v1/payment-intents/pi_... con pk_test_ y header X-Client-Secret" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;verticalAlign=bottom;labelBackgroundColor=#FFFFFF;strokeColor=#455A64;fontColor=#1A1A1A;fontSize=10;endArrow=block;endFill=1;exitX=1;exitY=0.255;exitDx=0;exitDy=0;entryX=0;entryY=0.255;entryDx=0;entryDy=0" edge="1" parent="1" source="ll-co" target="ll-pa">
          <mxGeometry relative="1" as="geometry" />
        </mxCell>
        <mxCell id="m06" value="6. 200 con checkout.payment_methods - TODAS las pasarelas habilitadas del tenant" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;verticalAlign=bottom;labelBackgroundColor=#FFFFFF;strokeColor=#455A64;fontColor=#1A1A1A;fontSize=10;dashed=1;endArrow=open;endFill=0;endSize=10;exitX=0;exitY=0.3;exitDx=0;exitDy=0;entryX=1;entryY=0.3;entryDx=0;entryDy=0" edge="1" parent="1" source="ll-pa" target="ll-co">
          <mxGeometry relative="1" as="geometry" />
        </mxCell>
        <mxCell id="m07" value="7. selector de medio de pago (solo si hay mas de una habilitada)" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;verticalAlign=bottom;labelBackgroundColor=#FFFFFF;strokeColor=#00838F;fontColor=#006064;fontSize=10;endArrow=block;endFill=1;exitX=0;exitY=0.345;exitDx=0;exitDy=0;entryX=1;entryY=0.345;entryDx=0;entryDy=0" edge="1" parent="1" source="ll-co" target="ll-br">
          <mxGeometry relative="1" as="geometry" />
        </mxCell>
        <mxCell id="m08" value="8. el comprador elige la pasarela" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;verticalAlign=bottom;labelBackgroundColor=#FFFFFF;strokeColor=#00838F;fontColor=#006064;fontSize=10;endArrow=block;endFill=1;exitX=1;exitY=0.39;exitDx=0;exitDy=0;entryX=0;entryY=0.39;entryDx=0;entryDy=0" edge="1" parent="1" source="ll-br" target="ll-co">
          <mxGeometry relative="1" as="geometry" />
        </mxCell>
        <mxCell id="m09" value="9. POST /v1/payment-intents/pi_.../confirm con el gateway_id elegido - PRIMER confirm" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;verticalAlign=bottom;labelBackgroundColor=#FFFFFF;strokeColor=#1565C0;fontColor=#0D47A1;fontSize=10;fontStyle=1;endArrow=block;endFill=1;exitX=1;exitY=0.435;exitDx=0;exitDy=0;entryX=0;entryY=0.435;entryDx=0;entryDy=0" edge="1" parent="1" source="ll-co" target="ll-pa">
          <mxGeometry relative="1" as="geometry" />
        </mxCell>
        <mxCell id="m10" value="10. createPayment con la return_url persistida al crear el intent" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;verticalAlign=bottom;labelBackgroundColor=#FFFFFF;strokeColor=#455A64;fontColor=#1A1A1A;fontSize=10;endArrow=block;endFill=1;exitX=1;exitY=0.48;exitDx=0;exitDy=0;entryX=0;entryY=0.48;entryDx=0;entryDy=0" edge="1" parent="1" source="ll-pa" target="ll-pg">
          <mxGeometry relative="1" as="geometry" />
        </mxCell>
        <mxCell id="m11" value="11. referencia de la transaccion y URL de su formulario de pago" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;verticalAlign=bottom;labelBackgroundColor=#FFFFFF;strokeColor=#455A64;fontColor=#1A1A1A;fontSize=10;dashed=1;endArrow=open;endFill=0;endSize=10;exitX=0;exitY=0.525;exitDx=0;exitDy=0;entryX=1;entryY=0.525;entryDx=0;entryDy=0" edge="1" parent="1" source="ll-pg" target="ll-pa">
          <mxGeometry relative="1" as="geometry" />
        </mxCell>
        <mxCell id="m12" value="12. 200 con status REQUIRES_ACTION y redirect_url" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;verticalAlign=bottom;labelBackgroundColor=#FFFFFF;strokeColor=#455A64;fontColor=#1A1A1A;fontSize=10;dashed=1;endArrow=open;endFill=0;endSize=10;exitX=0;exitY=0.57;exitDx=0;exitDy=0;entryX=1;entryY=0.57;entryDx=0;entryDy=0" edge="1" parent="1" source="ll-pa" target="ll-co">
          <mxGeometry relative="1" as="geometry" />
        </mxCell>
        <mxCell id="m13" value="13. redireccion top-level al formulario de la pasarela" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;verticalAlign=bottom;labelBackgroundColor=#FFFFFF;strokeColor=#455A64;fontColor=#1A1A1A;fontSize=10;endArrow=block;endFill=1;exitX=0;exitY=0.615;exitDx=0;exitDy=0;entryX=1;entryY=0.615;entryDx=0;entryDy=0" edge="1" parent="1" source="ll-co" target="ll-br">
          <mxGeometry relative="1" as="geometry" />
        </mxCell>
        <mxCell id="m14" value="14. el comprador paga con su tarjeta en el sitio de la pasarela (el PAN no toca ApiPay - PCI DSS SAQ A)" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;verticalAlign=bottom;labelBackgroundColor=#FFFFFF;strokeColor=#C62828;fontColor=#B71C1C;fontSize=10;endArrow=block;endFill=1;exitX=1;exitY=0.66;exitDx=0;exitDy=0;entryX=0;entryY=0.66;entryDx=0;entryDy=0" edge="1" parent="1" source="ll-br" target="ll-pg">
          <mxGeometry relative="1" as="geometry" />
        </mxCell>
        <mxCell id="m15" value="15. vuelve a la return_url, que en checkout alojado es el propio checkout" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;verticalAlign=bottom;labelBackgroundColor=#FFFFFF;strokeColor=#455A64;fontColor=#1A1A1A;fontSize=10;dashed=1;endArrow=open;endFill=0;endSize=10;exitX=0;exitY=0.705;exitDx=0;exitDy=0;entryX=1;entryY=0.705;entryDx=0;entryDy=0" edge="1" parent="1" source="ll-pg" target="ll-br">
          <mxGeometry relative="1" as="geometry" />
        </mxCell>
        <mxCell id="m16" value="16. retorno con el token de la pasarela y nada mas" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;verticalAlign=bottom;labelBackgroundColor=#FFFFFF;strokeColor=#455A64;fontColor=#1A1A1A;fontSize=10;endArrow=block;endFill=1;exitX=1;exitY=0.75;exitDx=0;exitDy=0;entryX=0;entryY=0.75;entryDx=0;entryDy=0" edge="1" parent="1" source="ll-br" target="ll-co">
          <mxGeometry relative="1" as="geometry" />
        </mxCell>
        <mxCell id="m17" value="17. POST /v1/payment-intents/pi_.../confirm con el token - SEGUNDO confirm" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;verticalAlign=bottom;labelBackgroundColor=#FFFFFF;strokeColor=#1565C0;fontColor=#0D47A1;fontSize=10;fontStyle=1;endArrow=block;endFill=1;exitX=1;exitY=0.795;exitDx=0;exitDy=0;entryX=0;entryY=0.795;entryDx=0;entryDy=0" edge="1" parent="1" source="ll-co" target="ll-pa">
          <mxGeometry relative="1" as="geometry" />
        </mxCell>
        <mxCell id="m18" value="18. 200 con el estado final del intent" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;verticalAlign=bottom;labelBackgroundColor=#FFFFFF;strokeColor=#455A64;fontColor=#1A1A1A;fontSize=10;dashed=1;endArrow=open;endFill=0;endSize=10;exitX=0;exitY=0.84;exitDx=0;exitDy=0;entryX=1;entryY=0.84;entryDx=0;entryDy=0" edge="1" parent="1" source="ll-pa" target="ll-co">
          <mxGeometry relative="1" as="geometry" />
        </mxCell>
        <mxCell id="m19" value="19. pagina de resultado, con el boton &quot;Volver a la tienda&quot; si hay merchant_return_url" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;verticalAlign=bottom;labelBackgroundColor=#FFFFFF;strokeColor=#00838F;fontColor=#006064;fontSize=10;endArrow=block;endFill=1;exitX=0;exitY=0.885;exitDx=0;exitDy=0;entryX=1;entryY=0.885;entryDx=0;entryDy=0" edge="1" parent="1" source="ll-co" target="ll-br">
          <mxGeometry relative="1" as="geometry" />
        </mxCell>
        <mxCell id="m20" value="20. el comprador vuelve a la tienda por merchant_return_url" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;verticalAlign=bottom;labelBackgroundColor=#FFFFFF;strokeColor=#F9A825;fontColor=#8D6E00;fontSize=10;endArrow=block;endFill=1;exitX=0;exitY=0.93;exitDx=0;exitDy=0;entryX=1;entryY=0.93;entryDx=0;entryDy=0" edge="1" parent="1" source="ll-br" target="ll-ec">
          <mxGeometry relative="1" as="geometry" />
        </mxCell>

        <mxCell id="nota-checkouturl" value="Paso 2 - checkout_url SOLO se emite al CREAR (201). Es el unico instante en que el client_secret existe en claro, asi que un GET posterior NO puede reconstruirla y OMITE el campo: si el comercio la pierde, tiene que crear otro intent. Se omite tambien si el despliegue no tiene base de checkout configurada o si el tenant no declaro clave publicable." style="shape=note;size=16;whiteSpace=wrap;html=1;fillColor=#FDECEA;strokeColor=#C62828;fontColor=#1A1A1A;fontSize=10;align=left;verticalAlign=top;spacingLeft=8;spacingTop=4" vertex="1" parent="1">
          <mxGeometry x="40" y="1190" width="310" height="150" as="geometry" />
        </mxCell>
        <mxCell id="nota-fragmento" value="Paso 4 - el client_secret viaja en el FRAGMENTO de la URL, no en la query. Es deliberado: el fragmento no llega a los logs del servidor ni a la cabecera Referer cuando el navegador salta a la pasarela. El checkout lo lee, lo guarda en sessionStorage y lo borra del historial con history.replaceState()." style="shape=note;size=16;whiteSpace=wrap;html=1;fillColor=#FFFDE7;strokeColor=#F9A825;fontColor=#1A1A1A;fontSize=10;align=left;verticalAlign=top;spacingLeft=8;spacingTop=4" vertex="1" parent="1">
          <mxGeometry x="370" y="1190" width="310" height="150" as="geometry" />
        </mxCell>
        <mxCell id="nota-selector" value="Pasos 6 y 7 - CheckoutSessionService.configFor recorta la lista a una sola pasarela cuando el intent YA tiene una; sin pasarela devuelve la lista COMPLETA de las habilitadas del tenant. Con una sola habilitada, mapIntentToUiState va directo al flujo y el selector no aparece. Ojo: en modo hub gateway_id llega null hasta que el comprador elige, aunque el contrato lo declare required." style="shape=note;size=16;whiteSpace=wrap;html=1;fillColor=#FFFDE7;strokeColor=#F9A825;fontColor=#1A1A1A;fontSize=10;align=left;verticalAlign=top;spacingLeft=8;spacingTop=4" vertex="1" parent="1">
          <mxGeometry x="700" y="1190" width="310" height="150" as="geometry" />
        </mxCell>
        <mxCell id="nota-cierre" value="Por que NO preseleccionar gateway_id al crear, que es lo contraintuitivo de este flujo. resolveConfirmGateway solo deja cambiar de pasarela MIENTRAS el intent no tiene gatewayReference. Si se preselecciona, el intent nace atado y cualquier fallo obliga a crear otro. Sin preseleccionar, un fallo ANTERIOR a la referencia todavia permite elegir otra sobre el MISMO intent. Un fallo POSTERIOR (tarjeta rechazada en Webpay, que ya creo su transaccion) si obliga a empezar de nuevo, y eso es correcto: cambiar de pasarela con una transaccion PENDING en la primera arriesga un doble cobro. Paso 16: se vuelve con el token de la pasarela y nada mas, por eso hostedSession recupera el client_secret de sessionStorage." style="shape=note;size=16;whiteSpace=wrap;html=1;fillColor=#E8EAF6;strokeColor=#283593;fontColor=#1A1A1A;fontSize=11;align=left;verticalAlign=top;spacingLeft=8;spacingTop=4" vertex="1" parent="1">
          <mxGeometry x="40" y="1360" width="970" height="130" as="geometry" />
        </mxCell>
      </root>
    </mxGraphModel>
  </diagram>
</mxfile>
