SUI Kiosk Implementation

Hello again my fellow SuiMove travellers. I am trying to build my first Kiosk app. My script is as below:

#[allow(unused)]
module try::kiosk;

use std::string::{Self, String};
use sui::coin::{Self, Coin};
use sui::sui::SUI;
use sui::package::{Self, Publisher};
use sui::transfer_policy::{Self, TransferPolicy, TransferPolicyCap, TransferRequest};
use sui::kiosk::{Self, Kiosk, KioskOwnerCap};

const EIncorrectArgument: u64 = 0;
const EInsufficientAmount: u64 = 1;
const MAX_BPS: u16 = 10_000;

// Item for trade
public struct Item has key, store {
    id: UID,
    name: String,
}

// One-time-witness for publisher
public struct KIOSK has drop {}

// Rule for policy
public struct Rule has drop {}

// Config for rule
public struct Config has store, drop {
    amount_bp: u16,
    min_amount: u64,
}

// Init publisher
fun init(otw: KIOSK, ctx: &mut TxContext) {
    let publisher = package::claim(otw, ctx);
    transfer::public_transfer(publisher, tx_context::sender(ctx));
}

// Create kiosk
public entry fun new_kiosk(ctx: &mut TxContext) {
    let (kiosk, kiosk_owner_cap) = kiosk::new(ctx);
    transfer::public_share_object(kiosk);
    transfer::public_transfer(kiosk_owner_cap, tx_context::sender(ctx));
}

// Create item
public entry fun new_item(name: vector<u8>, ctx: &mut TxContext) {
    transfer::transfer(Item {
        id: object::new(ctx),
        name: string::utf8(name),
    }, tx_context::sender(ctx));
}

// Place item in kiosk
public entry fun place_item(
    kiosk: &mut Kiosk,
    kiosk_cap: &KioskOwnerCap,
    item: Item) {
        kiosk::place(kiosk, kiosk_cap, item);
}

// List item for sale
public entry fun list_item(
    kiosk: &mut Kiosk,
    kiosk_cap: &KioskOwnerCap,
    item_id: ID,
    price: u64) {
        kiosk::list<Item>(kiosk, kiosk_cap, item_id, price);
}

// Create TransferPolicy & TransferPolicyCap
#[allow(lint(share_owned, self_transfer))]
public entry fun new_policy(publisher: &Publisher, ctx: &mut TxContext) {
    let (policy, policy_cap) = transfer_policy::new<Item>(publisher, ctx);
    transfer::public_share_object(policy);
    transfer::public_transfer(policy_cap, tx_context::sender(ctx));
}

// Add rule to policy
public entry fun add_rule(
    policy: &mut TransferPolicy<Item>,
    policy_cap: &TransferPolicyCap<Item>,
    amount_bp: u16,
    min_amount: u64) {
        assert!(amount_bp <= MAX_BPS, EIncorrectArgument);
        transfer_policy::add_rule(Rule {}, policy, policy_cap, Config {  amount_bp, min_amount });
}

// Pay the royalty fee
public fun pay_fee(
    policy: &mut TransferPolicy<Item>,
    request: &mut TransferRequest<Item>,
    payment: Coin<SUI>) {
        let paid = transfer_policy::paid(request);
        let amount = fee_amount(policy, paid);
        assert!(coin::value(&payment) == amount, EInsufficientAmount);

        transfer_policy::add_to_balance(Rule {}, policy, payment);
        transfer_policy::add_receipt(Rule {}, request);
}

// Calculate the royalty fee
public fun fee_amount(policy: &TransferPolicy<Item>, paid: u64): u64 {
    let config: &Config = transfer_policy::get_rule(Rule {}, policy);
    let mut amount = (((paid as u128) * (config.amount_bp as u128) / 10_000) as u64);

    if (amount < config.min_amount) {
        amount = config.min_amount 
    };

    amount
}

// Purchase item from kiosk - IS THIS WHERE ALL GOES HAYWIRE ????
public entry fun buy_item(
    kiosk: &mut Kiosk,
    item_id: ID,
    payment: Coin<SUI>,
    policy: &TransferPolicy<Item>,
    buyer: address) {
        let (item, request) = kiosk::purchase(kiosk, item_id, payment);
        pay_fee(policy, &mut request, payment); 
        transfer_policy::confirm_request<Item>(policy, request);
        transfer::public_transfer(item, buyer);
}



When I compile it I get the following error msg:

error[E04006]: invalid subtype
    โ”Œโ”€ ./sources/try.move:138:9
    โ”‚
107 โ”‚     policy: &mut TransferPolicy<Item>,
    โ”‚             ------------------------- Expected: '&mut sui::transfer_policy::TransferPolicy<try::kiosk::Item>'
    ยท
135 โ”‚     policy: &TransferPolicy<Item>,
    โ”‚             --------------------- Given: '&sui::transfer_policy::TransferPolicy<try::kiosk::Item>'
    ยท
138 โ”‚         pay_fee(policy, &mut request, payment);
    โ”‚         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid call of 'try::kiosk::pay_fee'. Invalid argument for parameter 'policy'

Failed to build Move modules: Compilation error.

If I comment out the last entry function buy_item the code compiles. It runs succesfully on the SUI Client CLI (Sui Explorer is a bit whimsical at times and I have yet to tame SUI PTB).

I realize that the flow of purchasing from Kiosk should be:

Buyer โ†’ kiosk::purchase() โ†’ Item + TransferRequest โ†’ Subsequent calls to fulfill TransferRequest โ†’ transfer_policy::confirm_request() โ†’ Transfer Item under ownership

I confess that I am unable to implement that in code. Any help would be dearly appreciated.

I thank you in advance.

Theodoros