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 %}
+
+ {% 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.