diff --git a/make_post_sell/static/css/common.css b/make_post_sell/static/css/common.css index a39b59e..1c7cdfa 100644 --- a/make_post_sell/static/css/common.css +++ b/make_post_sell/static/css/common.css @@ -1635,6 +1635,22 @@ div.edit-page > section.edit-card-full { border-radius: var(--radius-md, 8px); } +/* Accepted-offer pay-link row shown to the seller: an input pre-filled + with the buyer's pay URL plus a copy-to-clipboard button. */ +.offer-pay-link-row { + display: grid; + grid-template-columns: 1fr auto; + gap: var(--space-2, 8px); + margin-top: var(--space-3, 12px); +} +.offer-pay-link { + width: 100%; + box-sizing: border-box; + padding: var(--space-2, 8px) var(--space-3, 12px); + font-family: var(--font-mono, ui-monospace, monospace); + font-size: var(--text-sm, 0.875rem); +} + /* Design-system settings form: stacked label + control + hint per field, two-up grid on wider viewports. Grid only — no flex. */ .settings-form { diff --git a/make_post_sell/templates/offer.j2 b/make_post_sell/templates/offer.j2 index b0812b3..5ffa80e 100644 --- a/make_post_sell/templates/offer.j2 +++ b/make_post_sell/templates/offer.j2 @@ -46,7 +46,7 @@ {% elif is_accepted %}
-

Offer accepted{% if request.user and request.user.uuid_str == buyer_id %} — pay now to complete your purchase{% endif %}.

+

Offer accepted{% if request.user and request.user.uuid_str == buyer_id %} — pay now to complete your purchase{% elif not is_paid %} — waiting on the buyer to pay ${{ "%.2f"|format(current_amount) }}{% endif %}.

{% elif can_act %}
@@ -97,13 +97,27 @@ {% endif %} - {# Pay-now CTA when the offer is accepted and the viewer is the buyer. #} - {% if is_accepted and request.user and request.user.uuid_str == buyer_id %} -
-
- -
-
+ {# Accepted-but-not-paid: the buyer gets the pay-now CTA; the seller + (or shop editor) gets a shareable link to send the buyer, since the + seller cannot pay on the buyer's behalf. #} + {% if is_accepted and not is_paid %} + {% if request.user and request.user.uuid_str == buyer_id %} +
+
+ +
+
+ {% elif request.user %} +
+

Awaiting payment

+

You accepted {{ buyer_name }}’s offer at ${{ "%.2f"|format(current_amount) }}. They need to sign in and pay from this same page — send them the link:

+ +
+ {% endif %} {% endif %}
diff --git a/make_post_sell/tests/test_functional.py b/make_post_sell/tests/test_functional.py index 1411783..4634eda 100644 --- a/make_post_sell/tests/test_functional.py +++ b/make_post_sell/tests/test_functional.py @@ -6810,6 +6810,26 @@ class TestOfferCheckout(_AuthenticatedBase): # ...and the redirect lands on that cart by id. self.assertIn(f"/cart/{match[0].uuid_str}", res.location) + def test_accepted_offer_seller_sees_pay_link_to_share(self): + offer_id = self._accepted_offer() + # _accepted_offer leaves user1 (seller / shop owner) logged in. + body = self.testapp.get(f"/o/{offer_id}", status=200).body.decode() + self.assertIn("Awaiting payment", body) + self.assertIn("offer-pay-link", body) + self.assertIn("waiting on the buyer to pay $75.00", body) + # Seller never sees the buyer's pay-now form (they cannot pay). + self.assertNotIn(f"/o/{offer_id}/checkout", body) + + def test_accepted_offer_buyer_sees_pay_now(self): + offer_id = self._accepted_offer() + self.testapp.get("/log-out") + self.log_in_user(self.user2_creds) + body = self.testapp.get(f"/o/{offer_id}", status=200).body.decode() + self.assertIn(f"/o/{offer_id}/checkout", body) + self.assertIn("Pay $75.00 now", body) + # Buyer view does not show the seller's awaiting-payment block. + self.assertNotIn("Awaiting payment", body) + def test_non_buyer_checkout_blocked(self): offer_id = self._accepted_offer() # Logged in as user1 (seller). Should be blocked.